JavaScript Symbol
ES6 中的 JavaScript 引入了一种新的原始 数据类型,称为 Symbol
。Symbol 是不可变的(无法更改)且是唯一的。例如,
// two symbols with the same description
const value1 = Symbol('hello');
const value2 = Symbol('hello');
console.log(value1 === value2); // false
尽管 value1 和 value2 都包含相同的描述,但它们是不同的。
创建 Symbol
您可以使用 Symbol()
函数来创建 Symbol
。例如,
// creating symbol
const x = Symbol()
typeof x; // symbol
您可以将其描述作为可选的 字符串 传递。例如,
const x = Symbol('hey');
console.log(x); // Symbol(hey)
访问 Symbol 描述
要访问 Symbol 的描述,我们使用 .
运算符。例如,
const x = Symbol('hey');
console.log(x.description); // hey
将 Symbol 添加为对象键
您可以使用方括号 []
将 Symbol 添加为 对象 中的键。例如,
let id = Symbol("id");
let person = {
name: "Jack",
// adding symbol as a key
[id]: 123 // not "id": 123
};
console.log(person); // {name: "Jack", Symbol(id): 123}
Symbol 不包含在 for...in 循环中
for...in
循环不会遍历 Symbolic 属性。例如,
let id = Symbol("id");
let person = {
name: "Jack",
age: 25,
[id]: 12
};
// using for...in
for (let key in person) {
console.log(key);
}
输出
name age
在对象中使用 Symbol 的好处
如果相同的代码片段用于各种程序,那么最好在对象键中使用 Symbols
。这是因为您可以在不同的代码中使用相同的键名,并避免重复问题。例如,
let person = {
name: "Jack"
};
// creating Symbol
let id = Symbol("id");
// adding symbol as a key
person[id] = 12;
在上面的程序中,如果 person
对象也被另一个程序使用,那么您可能不希望添加一个可以被另一个程序访问或更改的属性。因此,通过使用 Symbol
,您可以创建一个可以使用的唯一属性。
现在,如果另一个程序也需要使用名为 id 的属性,只需添加一个名为 id
的 Symbol,就不会出现重复问题。例如,
let person = {
name: "Jack"
};
let id = Symbol("id");
person[id] = "Another value";
在上面的程序中,即使使用相同的名称来存储值,Symbol
数据类型也将具有唯一的值。
在上面的程序中,如果使用了字符串键,那么后面的程序将覆盖先前的值。例如,
let person = {
name: "Jack"
};
// using string as key
person.id = 12;
console.log(person.id); // 12
// Another program overwrites value
person.id = 'Another value';
console.log(person.id); // Another value
在上面的程序中,第二个 user.id
会覆盖之前的值。
Symbol 方法
Symbol 提供了各种可用方法。
方法 | 描述 |
---|---|
for() |
搜索现有 Symbol |
keyFor() |
从全局 Symbol 注册表中返回一个共享的 Symbol 键。 |
toSource() |
返回一个包含 Symbol 对象来源的字符串 |
toString() |
返回一个包含 Symbol 描述的字符串 |
valueOf() |
返回 Symbol 对象的原始值。 |
示例:Symbol 方法
// get symbol by name
let sym = Symbol.for('hello');
let sym1 = Symbol.for('id');
// get name by symbol
console.log( Symbol.keyFor(sym) ); // hello
console.log( Symbol.keyFor(sym1) ); // id
Symbol 属性
属性 | 描述 |
---|---|
asyncIterator |
返回对象的默认 AsyncIterator |
hasInstance |
确定构造函数对象是否将其实例识别为自身实例 |
isConcatSpreadable |
指示对象是否应展平为其数组元素 |
iterator |
返回对象的默认迭代器 |
匹配 |
与字符串匹配 |
matchAll |
返回一个迭代器,该迭代器根据字符串中的正则表达式生成匹配项 |
replace |
替换字符串的匹配子字符串 |
search |
返回字符串中与正则表达式匹配的索引 |
split |
在与正则表达式匹配的索引处拆分字符串 |
species |
创建派生对象 |
toPrimitive |
将对象转换为原始值 |
toStringTag |
提供对象的默认描述 |
description |
返回一个包含 Symbol 描述的字符串 |
示例:Symbol 属性示例
const x = Symbol('hey');
// description property
console.log(x.description); // hey
const stringArray = ['a', 'b', 'c'];
const numberArray = [1, 2, 3];
// isConcatSpreadable property
numberArray[Symbol.isConcatSpreadable] = false;
let result = stringArray.concat(numberArray);
console.log(result); // ["a", "b", "c", [1, 2, 3]]
另请阅读