测验

JavaScript 中 `Symbol` 的用途是什么?

主题
JavaScript
在GitHub上编辑

总结

JavaScript 中的 Symbol 是 ES6 (ECMAScript 2015) 中引入的一种新的原始数据类型。它们是唯一的、不可变的标识符,主要用于对象属性键,以避免名称冲突。这些值可以使用 Symbol(...) 函数创建,并且每个 Symbol 值都保证是唯一的,即使它们具有相同的键/描述。Symbol 属性在 for...in 循环或 Object.keys() 中不可枚举,这使得它们适合创建私有/内部对象状态。

let sym1 = Symbol();
let sym2 = Symbol('myKey');
console.log(typeof sym1); // "symbol"
console.log(sym1 === sym2); // false, because each symbol is unique
let obj = {};
let sym = Symbol('uniqueKey');
obj[sym] = 'value';
console.log(obj[sym]); // "value"

注意Symbol() 函数必须在没有 new 关键字的情况下调用。它并不完全是一个构造函数,因为它只能作为函数调用,而不是使用 new Symbol()


JavaScript 中的 Symbol

JavaScript 中的 Symbols 是一种独特且不可变的数据类型,主要用于对象属性键,以避免名称冲突。

关键特征

  • 唯一性:每个 Symbol 值都是唯一的,即使它们具有相同的描述。
  • 不可变性:Symbol 值是不可变的,这意味着它们的值不能被更改。
  • 不可枚举性:Symbol 属性不包含在 for...in 循环或 Object.keys() 中。

创建 Symbol

Symbol 可以使用 Symbol() 函数创建:

const sym1 = Symbol();
const sym2 = Symbol('uniqueKey');
console.log(typeof sym1); // "symbol"
console.log(sym1 === sym2); // false, because each symbol is unique

必须在没有 new 关键字的情况下调用 Symbol(..) 函数。

Symbol 用作 object 属性键

Symbol 可用于将属性添加到对象,而不会有名称冲突的风险:

const obj = {};
const sym = Symbol('uniqueKey');
obj[sym] = 'value';
console.log(obj[sym]); // "value"

Symbol 不可枚举

  • Symbol 属性不包含在 for...in 循环或 Object.keys() 中。
  • 这使得它们适合创建私有/内部对象状态。
  • 使用 Object.getOwnPropertySymbols(obj) 获取对象上的所有 symbol 属性。
const mySymbol = Symbol('privateProperty');
const obj = {
name: 'John',
[mySymbol]: 42,
};
console.log(Object.keys(obj)); // Output: ['name']
console.log(obj[mySymbol]); // Output: 42

全局 Symbol 注册表

您可以使用 Symbol.for('key') 创建全局 Symbol,如果全局注册表中不存在,则创建一个新的 Symbol,或者返回现有的 Symbol。这允许您在代码库的不同部分甚至不同的代码库之间重用 Symbol

const globalSym1 = Symbol.for('globalKey');
const globalSym2 = Symbol.for('globalKey');
console.log(globalSym1 === globalSym2); // true
const key = Symbol.keyFor(globalSym1);
console.log(key); // "globalKey"

众所周知的 Symbol

JavaScript 包含几个内置的 Symbol,称为众所周知的 Symbol

  • Symbol.iterator:定义对象的默认 iterator
  • Symbol.toStringTag:用于创建对象的字符串描述。
  • Symbol.hasInstance:用于确定对象是否是构造函数的实例。

Symbol.iterator

let iterable = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step <= 5) {
return { value: step, done: false };
}
return { done: true };
},
};
},
};
for (let value of iterable) {
console.log(value); // 1, 2, 3, 4, 5
}

Symbol.toStringTag

let myObj = {
[Symbol.toStringTag]: 'MyCustomObject',
};
console.log(Object.prototype.toString.call(myObj)); // "[object MyCustomObject]"

总结

Symbol 是 JavaScript 中一项强大的功能,尤其适用于创建唯一的对象属性和自定义对象行为。它们提供了一种创建隐藏属性的方法,防止意外访问或修改,这在大型应用程序和库中特别有益。

延伸阅读

在GitHub上编辑