在Javascript的新标准ES6中,Symbol类型是一个重要的新增特性。它是一种特殊的 "原始" 数据类型,可以用来作为对象属性的键(key),从而提供更好的对象属性处理和保护的功能。接下来我们将详细探讨Symbol类型的用法和相关特性。
Symbol 简介
在ES6之前,对于对象属性名称(键)的处理,我们只能使用字符串。ES6中引入了新增数据类型Symbol,它可以作为对象属性的键,作为区分其他类型键的一种特殊方式。Symbol值是不可变的,可以保证每个属性键的唯一性。Symbol类型的一个重要特点是它不会被暴露给开发者,因此它可以使用作保护性属性,避免意外更改对象的键。
const sym = Symbol(); console.log(typeof sym); // "symbol"
同时,Symbol()方法可以带有一个参数,用于标识该Symbol的描述。
const mySym = Symbol('My Symbol'); console.log(mySym); // "Symbol(My Symbol)"
使用 Symbol 作为对象属性名
我们可以使用Symbol作为对象的属性名。使用Symbol作为对象的属性名有两种方法,一种是使用 symbol
方法(例如,let mySym = Symbol();
),另一种是使用 Symbol的描述(例如,let mySym = Symbol('My Symbol');
)。下面看一段示例代码:
const mySym = Symbol('My Symbol'); const myObj = { [mySym]: 'Symbol as property name' }; console.log(myObj[mySym]); // "Symbol as property name"
使用 []
运算符可以访问 Symbol 类型的属性值。因为每个Symbol值都是唯一的,所以我们将Symbol用于对象属性名,可以避免对象属性名冲突的情况。
Symbol 用作常量集合
由于Symbol是独一无二的,我们可以使用Symbol来创建常量集合。ES6推荐使用常量集合来取代枚举类型,因为常量集合的值都是唯一的,不同于枚举类型,集合元素中的值不会改变,从而防止了程序运行时改变或者误操作导致的bug。
const MY_SYMBOLS = { A: Symbol('A'), B: Symbol('B'), C: Symbol('C') }; console.log(MY_SYMBOLS.A); // Symbol(A) console.log(MY_SYMBOLS.B); // Symbol(B) console.log(MY_SYMBOLS.C); // Symbol(C)
由于Symbol的唯一性,我们可以通过Symbol这种数据类型来确保集合元素的唯一性,避免程序中重复定义的问题,并且代码可读性更好。
JavaScript 内置 Symbol 类型
在ES6中,JavaScript引入了许多预定义的Symbol值,这些Symbol值以Symbol. 开头的表达式表示,下面我们来介绍一下其中几个常用Symbol内置类型。
Symbol.iterator
Symbol.iterator是一个预定义的Symbol值,在诸如数组、字符串、Set、Map等可迭代对象中使用的特殊方法。每个可迭代对象都有一个默认迭代器,并且在遍历过程中会使用Symbol.iterator进行迭代,可用于自定义迭代器,从而实现更好的迭代操作。
const myArr = [1, 2, 3]; const myIter = myArr[Symbol.iterator](); console.log(myIter.next()); // {value: 1, done: false} console.log(myIter.next()); // {value: 2, done: false} console.log(myIter.next()); // {value: 3, done: false} console.log(myIter.next()); // {value: undefined, done: true}
Symbol.match
使用 Symbol.match 可以实现自定义正则表达式中使用的匹配规则,例如,
const mySymbol = Symbol('My Symbol'); String.prototype[mySymbol] = function(s) { // 定义匹配规则 console.log(s.match(/hello/g)); }; 'hello world'.match(new RegExp('hello')[mySymbol]); // 输出:["hello"]
通过在String.prototype
中定义自己独有的匹配规则,可以更好地进行特定情况下的文本解析。
Symbol.toPrimitive
Symbol.toPrimitive也是一个预定义的Symbol,用于指定对象转变为普通类型的逻辑。当我们把一个对象转变成非对象类型的数据(如字符串或数字),或者把它们传递给一个期望非对象类型数据的函数时,Javascript会使用Symbol.toPrimitive来转换它们的值。
const mySym = Symbol('mySym'); const myObj = { [mySym]: 'My Symbol' }; console.log(myObj + ''); // "[object Object]" console.log(myObj[Symbol.toPrimitive]('string')); // "My Symbol" console.log(myObj[mySym]); // "My Symbol"
总结
Symbol类型提供了一个非常有用的工具,在对象属性处理、常量集合定义、集合元素的唯一性确认等场景下都有广泛的应用,大大提高了代码可读性和可维护性。但Symbol作为一种新的数据类型,其目前的支持度还不是很完善,我们需要根据实际情况来判断它的可行性和适用性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e2f491f6b2d6eab3e41131