ES6/ES7/ES8/ES9 中的 Symbol 使用详解

Symbol 是 ES6 引入的一种新的原始数据类型,它可以用来创建唯一的标识符,解决了对象属性名冲突的问题。在 ES7、ES8、ES9 中,Symbol 也得到了进一步的扩展和完善。本文将详细介绍 Symbol 的使用方法及其在前端开发中的应用。

创建 Symbol

Symbol 可以通过 Symbol() 函数创建,该函数接受一个可选的字符串参数,用于指定 Symbol 的描述信息。例如:

const sym1 = Symbol();
const sym2 = Symbol('foo');

上述代码中,sym1 和 sym2 都是不同的 Symbol,因为每个 Symbol 都是唯一的,即使描述信息相同。

Symbol 作为对象属性名

Symbol 可以作为对象属性名,这样可以避免属性名冲突的问题。例如:

const obj = {};
const sym = Symbol('foo');

obj[sym] = 'bar';

console.log(obj[sym]); // 'bar'

上述代码中,我们使用 Symbol('foo') 创建了一个 Symbol,并将其作为 obj 对象的属性名。此时,obj[sym] 等价于 obj.foo,但是前者不会与其他属性名冲突。

Symbol.for() 和 Symbol.keyFor()

Symbol.for() 方法可以创建或获取全局 Symbol,它接受一个字符串参数,用于指定 Symbol 的名称。例如:

const sym1 = Symbol.for('foo');
const sym2 = Symbol.for('foo');

console.log(sym1 === sym2); // true

上述代码中,sym1 和 sym2 都是名称为 'foo' 的全局 Symbol,它们是相等的,因为它们具有相同的名称。

Symbol.keyFor() 方法可以获取全局 Symbol 的名称,它接受一个 Symbol 参数。例如:

const sym = Symbol.for('foo');

console.log(Symbol.keyFor(sym)); // 'foo'

上述代码中,我们获取了名称为 'foo' 的全局 Symbol,并通过 Symbol.keyFor() 方法获取了它的名称。

Symbol 的内置值

ES6 中有一些内置的 Symbol 值,它们在特定的对象上有特定的用途。下面是一些常用的内置 Symbol 值:

  • Symbol.iterator:用于定义对象的默认迭代器方法。
  • Symbol.match:用于指定对象的正则匹配方法。
  • Symbol.replace:用于指定对象的字符串替换方法。
  • Symbol.search:用于指定对象的字符串搜索方法。
  • Symbol.species:用于指定对象的默认构造函数。
  • Symbol.toPrimitive:用于指定对象的默认的转换方法。
  • Symbol.toStringTag:用于指定对象的默认字符串描述。

例如,我们可以使用 Symbol.iterator 定义一个可迭代对象:

const myIterable = {};
myIterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

for (let value of myIterable) {
  console.log(value);
}
// Output:
// 1
// 2
// 3

上述代码中,我们使用 Symbol.iterator 定义了 myIterable 对象的默认迭代器方法,使其成为一个可迭代对象,可以使用 for...of 循环遍历它的值。

总结

Symbol 是一种新的原始数据类型,它可以用来创建唯一的标识符,解决了对象属性名冲突的问题。在 ES6、ES7、ES8、ES9 中,Symbol 也得到了进一步的扩展和完善。通过 Symbol.for() 方法,我们可以创建或获取全局 Symbol,通过 Symbol.keyFor() 方法,我们可以获取全局 Symbol 的名称。此外,ES6 中还有一些内置的 Symbol 值,它们在特定的对象上有特定的用途。在前端开发中,我们可以使用 Symbol 来避免对象属性名冲突,定义可迭代对象等。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c31523add4f0e0ffd229f0