JavaScript 符号
提示
- 唯一性和不变性:JavaScript 中的
Symbol
是一种原始数据类型,用于创建唯一且不可变的标识符。例如,Symbol('hello')
和Symbol('hello')
即使描述相同,也是不同的符号。 - 创建和使用 Symbol:使用
Symbol()
函数创建 Symbol,可选地带有描述字符串。Symbol 可作为对象的键使用,但不会被常规的for...in
循环遍历。 - Symbol 的优势和方法:
- 使用 Symbol 作为对象键可避免属性名冲突,尤其在多个独立代码片段操作同一对象时。
- Symbol 提供了方法如
Symbol.for()
和Symbol.keyFor()
,以及属性如Symbol.description
和Symbol.isConcatSpreadable
。
JavaScript Symbol
JavaScript ES6 引入了一种名为 Symbol
的新原始数据类型。Symbol是不可变(不能被改变)且唯一的。例如,
// 两个具有相同描述的symbol
const value1 = Symbol("hello");
const value2 = Symbol("hello");
console.log(value1 === value2); // false
尽管value1和value2都包含相同的描述,它们是不同的。
创建Symbol
您可以使用Symbol()
函数来创建一个Symbol
。例如,
// 创建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",
// 添加symbol作为键
[id]: 123, // 而不是 "id": 123
};
console.log(person); // {name: "Jack", Symbol(id): 123}
for...in循环不包括Symbol属性
for...in
循环不会迭代Symbol属性。例如,
let id = Symbol("id");
let person = {
name: "Jack",
age: 25,
[id]: 12,
};
// 使用for...in
for (let key in person) {
console.log(key);
}
输出
name;
age;
在对象中使用Symbol的好处
如果相同的代码片段在不同程序中使用,那么最好在对象键中使用Symbols
。这是因为您可以在不同代码中使用相同的键名,避免重复问题。例如,
let person = {
name: "Jack",
};
// 创建Symbol
let id = Symbol("id");
// 添加symbol作为键
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",
};
// 使用字符串作为键
person.id = 12;
console.log(person.id); // 12
// 另一个程序覆盖值
person.id = "Another value";
console.log(person.id); // Another value
在上述程序中,第二个user.id
覆盖了先前的值。
Symbol方法
Symbol提供了各种方法。
方法 | 描述 |
---|---|
for() | 搜索现有的symbols |
keyFor() | 从全局symbol注册表返回共享symbol键 |
toSource() | 返回包含Symbol对象源代码的字符串 |
toString() | 返回包含Symbol描述的字符串 |
valueOf() | 返回Symbol对象的原始值 |
示例:Symbol方法
// 通过名称获取symbol
let sym = Symbol.for("hello");
let sym1 = Symbol.for("id");
// 通过symbol获取名称
console.log(Symbol.keyFor(sym)); // hello
console.log(Symbol.keyFor(sym1)); // id
Symbol属性
属性 | 描述 |
---|---|
asyncIterator | 返回对象的默认异步迭代器 |
hasInstance | 确定构造函数对象是否将某个对象视为其实例 |
isConcatSpreadable | 表明对象是否应该被展平为其数组元素 |
iterator | 返回对象的默认迭代器 |
match | 与字符串匹配 |
matchAll | 返回一个迭代器,该迭代器生成正则表达式与字符串的匹配项 |
replace | 替换字符串的匹配子串 |
search | 返回字符串中匹配正则表达式的索引 |
split | 在匹配正则表达式的索引处拆分字符串 |
species | 创建派生对象 |
toPrimitive | 将对象转换为原始值 |
toStringTag | 提供对象的默认描述 |
description | 返回包含symbol描述的字符串 |
示例:Symbol属性示例
const x = Symbol("hey");
// description属性
console.log(x.description); // hey
const stringArray = ["a", "b", "c"];
const numberArray = [1, 2, 3];
// isConcatSpreadable属性
numberArray[Symbol.isConcatSpreadable] = false;
let result = stringArray.concat(numberArray);
console.log(result); // ["a", "b", "c", [1, 2, 3]]