Symbol

 

Symbol 是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用。Symbol 对象是一个 symbol primitive data type 的隐式对象包装器。

symbol 数据类型是一个 primitive data type

语法

Symbol([description])

参数

description 可选
可选的,字符串。可用于调试但不能访问符号本身的符号描述。

描述

要创建一个新的基本 symbol,你可以使用一个可选的字符串作为其描述,写Symbol().

var sym0 = Symbol();
var sym1 = Symbol("symbol1");
var sym2 = Symbol("symbol2");
var sym3 = Symbol("symbol2");

 

上面的代码创建三个新的symbols。 注意,Symbol("symbol2") 不会强制字符串 “symbol2” 成为一个 symbol。它每次都会创建一个新的 symbol:

Symbol("symbol2") === Symbol("symbol2"); // false

下面使用 new 运算符的语法将会抛出一个 TypeError 错误:

var sym = new Symbol(); // TypeError

这会阻止创建一个显式的 Symbol 包装器对象而不是一个 Symbol 值。围绕原始数据类型创建一个显式包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,如 new Boolean、 new String以及new Number因为遗留原因仍可被创建。

如果你真地想创建一个 Symbol 包装对象(Symbol wrapper object),你可以使用 Object() 函数:

var sym = Symbol("foo");
typeof sym;     // "symbol"
var symObj = Object(sym);
typeof symObj;  // "object"

全局共享的 Symbol

上面的语法使用Symbol() 函数 不会在你的整个代码库中创建一个可用的全局符号。 要创建跨文件可用的symbols,甚至跨域(每个都有它自己的全局作用域) , 使用这个方法Symbol.for()Symbol.keyFor() 从全局symbol的注册处设置和取得symbols。

在对象中查找 Symbol 属性

方法Object.getOwnPropertySymbols() 让你在查找一个给定对象的符号属性时返回一个符号类型的数组。注意,每个初始化的对象都是没有自己的符号属性的,因此这个数组可能为空。除非你已经在对象上设置了符号属性。

属性

Symbol.length
长度属性值为1。
Symbol.name
仅Chrome/v8。返回符号描述。
Symbol.prototype
描述符号构造函数的原型。

众所周知的符号

除了你自己的符号,JavaScript还内建了一些在ECMAScript 5 之前没有暴露给开发者的符号,它们代表了内部语言行为。这些符号可以使用以下属性访问:

迭代 symbols

Symbol.iterator
一个返回一个对象默认迭代器的方法。使用 for...of.

正则表达式 symbols

Symbol.match
一个用于对字符串进行匹配的方法,也用于确定一个对象是否可以作为正则表达式使用。使用 String.prototype.match().
Symbol.replace
一个替换匹配字符串的子串的方法. 使用 String.prototype.replace().
Symbol.search
一个返回一个字符串中与正则表达式相匹配的索引的方法。使用String.prototype.search().
Symbol.split
一个在匹配正则表达式的索引处拆分一个字符串的方法.。使用 String.prototype.split().

其他 symbols

Symbol.hasInstance
一个确定一个构造器对象识别的对象是否为它的实例的方法。使用 instanceof.
Symbol.isConcatSpreadable
一个布尔值,表明一个对象是否应该flattened为它的数组元素。使用Array.prototype.concat().
Symbol.unscopables
拥有和继承属性名的一个对象的值被排除在与环境绑定的相关对象外。
Symbol.species
一个用于创建派生对象的构造器函数。.
Symbol.toPrimitive
一个将对象转化为基本数据类型的方法。
Symbol.toStringTag
用于对象的默认描述的字符串值。使用Object.prototype.toString().

方法

Symbol.for(key)
使用给定的key搜索现有符号,如果找到则返回符号。否则将得到一个新的使用给定的key在全局符号注册表中创建的符号。
Symbol.keyFor(sym)
为给定符号从全局符号注册表中检索一个共享符号键。

Symbol 原型

所有 Symbol 继承自 Symbol.prototype.

属性

Symbol.prototype.constructor
返回创建实例原型的函数. 默认为 Symbol 函数。

方法

Symbol.prototype.toSource()
返回包含Symbol 对象源码的字符串。覆盖Object.prototype.toSource() 方法。
Symbol.prototype.toString()
返回包含Symbol描述符的字符串。 覆盖Object.prototype.toString() 方法。
Symbol.prototype.valueOf()
返回 Symbol 对象的初始值.。覆盖 Object.prototype.valueOf() 方法。
Symbol.prototype[@@toPrimitive]
 返回Symbol对象的初始值。

示例

对 symbol 使用 typeof 运算符

 typeof运算符能帮助你识别(标识)symbol

typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'

Symbol 类型转换

当使用 symbol 值进行类型转换时需要注意一些事情:

  • 尝试将一个 symbol 值转换为一个 number 值时,会抛出一个 TypeError 错误  (e.g. +sym or sym | 0).
  • 使用宽松相等时, Object(sym) == sym returns true.
  • 这会阻止你从一个 symbol 值隐式地创建一个新的 string 类型的属性名。例如,Symbol("foo") + "bar" 将抛出一个 TypeError (can't convert symbol to string).
  • "safer" String(sym) conversion works like a call to Symbol.prototype.toString() with symbols,但是注意 new String(sym) 将抛出异常。

Symbols 与 for...in 迭代

Symbols 在 for...in 迭代中不可枚举。另外,Object.getOwnPropertyNames() 不会返回 symbol 对象的属性,但是你能使用 Object.getOwnPropertySymbols() 得到它们。

var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for (var i in obj) {
   console.log(i); // logs "c" and "d"
}

Symbols 与 JSON.stringify()

当使用 JSON.strIngify() 时以 symbol 值作为键的属性会被完全忽略:

JSON.stringify({[Symbol("foo")]: "foo"});
// '{}'

更多细节,请看 JSON.stringify()

Symbol 包装器对象作为属性的键

当一个 Symbol 包装器对象作为一个属性的键时,这个对象将被强制转换为它的包装过的 symbol 值:

var sym = Symbol("foo");
var obj = {[sym]: 1};
obj[sym];            // 1
obj[Object(sym)];    // still 1

技术标准

标准 状态 注释
ECMAScript 2015 (6th Edition, ECMA-262)
Symbol
Standard 原始定义
ECMAScript Latest Draft (ECMA-262)
Symbol
Living Standard  

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 38 36.0 (36.0) 未实现 25 未实现
Symbol.iterator (@@iterator) 38 36.0 (36.0) 未实现 25 未实现
Symbol.unscopables (@@unscopables) 38 未实现 未实现 25 未实现
Symbol.match (@@match) 未实现 40.0 (40.0) 未实现 未实现 未实现
Symbol.species (@@species) 未实现 41.0 (41.0) 未实现 未实现 未实现
Symbol.toPrimitive (@@toPrimitive) 未实现 44.0 (44.0) 未实现 未实现 未实现
Other well-known symbols 未实现 未实现 未实现 未实现 未实现
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 未实现 38 36.0 (36.0) 未实现 25 未实现
Symbol.iterator (@@iterator) 未实现 38 36.0 (36.0) 未实现 25 未实现
Symbol.unscopables (@@unscopables) 未实现 38 未实现 未实现 25 未实现
Symbol.match (@@match) 未实现 未实现 40.0 (40.0) 未实现 未实现 未实现
Symbol.species (@@species) 未实现 未实现 41.0 (41.0) 未实现 未实现 未实现
Symbol.toPrimitive (@@toPrimitive) 未实现 未实现 44.0 (44.0) 未实现 未实现 未实现
Other well-known symbols 未实现 未实现 未实现 未实现 未实现 未实现

参考文档

文档标签和贡献者