跳到主要内容

JavaScript 符号

提示
  1. 唯一性和不变性:JavaScript 中的 Symbol 是一种原始数据类型,用于创建唯一且不可变的标识符。例如,Symbol('hello')Symbol('hello') 即使描述相同,也是不同的符号。
  2. 创建和使用 Symbol:使用 Symbol() 函数创建 Symbol,可选地带有描述字符串。Symbol 可作为对象的键使用,但不会被常规的 for...in 循环遍历。
  3. Symbol 的优势和方法
    • 使用 Symbol 作为对象键可避免属性名冲突,尤其在多个独立代码片段操作同一对象时。
    • Symbol 提供了方法如 Symbol.for()Symbol.keyFor(),以及属性如 Symbol.descriptionSymbol.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]]