符号
多个接口可能为不同的事物使用相同的属性名称。 例如,我可以定义一个接口,其中toString
方法应该将对象转换为一段纱线。 一个对象不可能同时满足这个接口和toString
的标准用法。
这是一个坏主意,这个问题并不常见。 大多数 JavaScript 程序员根本就不会去想它。 但是,语言设计师们正在思考这个问题,无论如何都为我们提供了解决方案。
当我声称属性名称是字符串时,这并不完全准确。 他们通常是,但他们也可以是符号(symbol)。 符号是使用Symbol
函数创建的值。 与字符串不同,新创建的符号是唯一的 - 你不能两次创建相同的符号。
let sym = Symbol("name");
console.log(sym == Symbol("name"));
// → false
Rabbit.prototype[sym] = 55;
console.log(blackRabbit[sym]);
// → 55
将Symbol
转换为字符串时,会得到传递给它的字符串,例如,在控制台中显示时,符号可以更容易识别。 但除此之外没有任何意义 - 多个符号可能具有相同的名称。
由于符号既独特又可用于属性名称,因此符号适合定义可以和其他属性共生的接口,无论它们的名称是什么。
const toStringSymbol = Symbol("toString");
Array.prototype[toStringSymbol] = function() {
return `${this.length} cm of blue yarn`;
};
console.log([1, 2].toString());
// → 1,2
console.log([1, 2][toStringSymbol]());
// → 2 cm of blue yarn
通过在属性名称周围使用方括号,可以在对象表达式和类中包含符号属性。 这会导致属性名称的求值,就像方括号属性访问表示法一样,这允许我们引用一个持有该符号的绑定。
let stringObject = {
[toStringSymbol]() { return "a jute rope"; }
};
console.log(stringObject[toStringSymbol]());
// → a jute rope