符号(Symbol)是 JavaScript 中的一种原始类型,用作非字符串的属性名。在 ES6 中,引入了符号作为属性名的机制,以解决属性名冲突和隐藏属性的需求。
符号的基本特点:
- 符号没有字面量语法,要获取一个符号值,需要调用 Symbol() 函数。每次调用都会返回一个新的唯一的符号值。
- 符号作为属性名时,可以保证属性的独一无二,不会与其他属性冲突。
- 符号可以带有一个可选的字符串描述,用于调试和识别。
使用符号的例子:
let strName = "string name";
let symName = Symbol("prop name");
let o = {};
o[strName] = 1; // 使用字符串名定义一个属性
o[symName] = 2; // 使用符号名定义一个属性
console.log(o[strName]); // 输出 1,访问字符串名字的属性
console.log(o[symName]); // 输出 2,访问符号名字的属性
Symbol() 函数可选地接收一个字符串参数,用于创建一个带有描述的唯一的符号值。如果提供了字符串参数,那么调用返回符号值的 toString() 方法会在结果中包含该字符串。需要注意的是,使用相同的字符串参数调用两次 Symbol() 函数会得到两个完全不同的符号值。
下面是一个示例:
let sym = Symbol("syn_x");
console.log(sym.toString()); // 输出 "Symbol(syn_x)"
符号的唯一有趣方法之一就是其 toString() 方法,它返回一个描述性的字符串表示符号。
在使用符号时,有时我们希望符号对代码是私有的,以确保我们的代码的属性不会与其他代码的属性发生冲突。但有时我们也希望定义一些可以与其他代码共享的符号值,例如像 Symbol.iterator 一样的机制。
- 符号通常用作一种语言扩展机制,比如在 ES6 中用于定义可迭代对象的迭代器方法名。
- Symbol.for() 函数可以创建一个全局共享的符号值,以便与其他代码共享。
- Symbol.forO与Synbol()完全不同:SynbolO永远不会返回相同的值,而在以相同的字符串调用时Synbol.for()始终返回相同的值。
使用 Symbol.for() 创建共享的符号值:
let sharedSymbol1 = Symbol.for("shared");
let sharedSymbol2 = Symbol.for("shared");
console.log(sharedSymbol1 === sharedSymbol2); // 输出 true,两个符号值相同
console.log(sharedSymbol1.toString()); // 输出 "Symbol(shared)"
console.log(Symbol.keyFor(sharedSymbol2)); // 输出 "shared"
综上所述,符号提供了一种有效的机制来确保属性名的唯一性和隐藏性,同时也提供了一种与其他代码共享标识的方式。