Symbol
是 ES6 中新增的一种原始数据类型,它的主要作用是作为对象属性的唯一标识符。在 JavaScript 中,我们通常使用字符串作为对象属性名,但是这种方式有一个限制,就是字符串有可能被覆盖或者误修改,因此不能保证属性名的唯一性。而 Symbol
可以避免这个问题,因为每个 Symbol
都是不同的,即使两个 Symbol
的内容相同,它们也是不相等的。
创建 Symbol
创建 Symbol
有两种方式,一种是使用 Symbol()
函数,另一种是使用 Symbol.for()
函数。其中,Symbol()
创建的 Symbol
是在每次调用时都会创建一个新的 Symbol
,而 Symbol.for()
创建的 Symbol
是全局共享的,即如果多次调用 Symbol.for()
传入相同的字符串参数,会返回同一个 Symbol
。
// javascriptcn.com 代码示例 // 创建一个独一无二的 Symbol const s1 = Symbol(); const s2 = Symbol(); console.log(s1 === s2); // false // 创建一个全局唯一的 Symbol const s3 = Symbol.for('mySymbol'); const s4 = Symbol.for('mySymbol'); console.log(s3 === s4); // true
当然,也可以给 Symbol
创建一个描述信息,方便调试和理解代码。
const s = Symbol('this is my symbol'); console.log(s.description); // 输出:this is my symbol
Symbol 作为对象属性名
使用 Symbol
作为对象属性名可以避免属性名冲突的问题。但是,由于 Symbol
是一种特殊的数据类型,因此无法使用点运算符来访问它们。要访问 Symbol
属性,必须使用方括号语法。
// javascriptcn.com 代码示例 const mySymbol = Symbol('my symbol'); const obj = { name: 'Tom', age: 18, [mySymbol]: 'Hello World', }; console.log(obj[mySymbol]); // 输出:Hello World console.log(obj.mySymbol); // 输出:undefined
内置 Symbol
在 ES6 中,还定义了一些内置 Symbol
,它们在语言层面上提供了一些内置的能力,可以用于定义对象的行为。下面我们介绍几个常用的内置 Symbol
。
Symbol.iterator
Symbol.iterator
是一个方法,它指向顺序访问可迭代对象的默认迭代器。默认情况下,JavaScript 内置了一些对象可以迭代,比如数组、字符串等。如果我们想自定义一个可以迭代的对象,只需要实现一个迭代器对象,然后将 Symbol.iterator
属性赋值为这个迭代器即可。
// javascriptcn.com 代码示例 const myIterable = {}; myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; for (const value of myIterable) { console.log(value); } // 输出: // 1 // 2 // 3
Symbol.match
Symbol.match
是一个方法,它指向一个正则表达式对象的方法,用于检查给定字符串是否能匹配正则表达式。在正则表达式调用 match()
方法时,会自动调用该方法。
const obj = { [Symbol.match]: function (str) { return 'hello world'.indexOf(str) !== -1; }, }; console.log('world'.match(obj)); // 输出:true console.log('foo'.match(obj)); // 输出:false
Symbol.toPrimitive
Symbol.toPrimitive
是一个方法,它指向一个对象的方法,用于将对象转换为原始类型的值。在某些情况下,需要将一个对象转换为原始值,比如使用 +
运算符进行类型转换,或者使用 Number()
或 String()
函数转换。默认情况下,JavaScript 会调用对象的 valueOf()
和 toString()
方法来进行转换,但是这两个方法可能不符合需求,因此可以使用 Symbol.toPrimitive
方法来定义对象的转换规则。
// javascriptcn.com 代码示例 const obj = { [Symbol.toPrimitive]: function (hint) { console.log('hint:', hint); if (hint === 'number') { return 42; } else if (hint === 'string') { return 'hello world'; } else { return true; } }, }; console.log(+obj); // 输出:hint: number,42 console.log(`${obj}`); // 输出:hint: string,hello world console.log(obj == true); // 输出:hint: default,true
总结
Symbol
是 ES6 中新增的一种原始数据类型,它作为对象属性的唯一标识符,可以避免属性名冲突的问题。除此之外,还可以被用于定义对象行为的内置 Symbol
,比如 Symbol.iterator
、Symbol.match
、Symbol.toPrimitive
等。
对于前端开发者来说,熟练掌握 Symbol
在对象属性、迭代器、正则表达式等方面的应用,可以提高代码的健壮性和可维护性。但是在实际开发中,由于 Symbol
的应用场景有限,也需要谨慎使用,避免增加代码的复杂性和理解难度。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6528eced7d4982a6ebb7ba0a