[ES6] Symbol
#
Symbol
Symbol([description])
description 可选,字符串。符号的描述是用于调试的而不是访问符号本身。
符号是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用。
符号对象是一个符号 原始数据类型的隐式对象包装器。
#创建一个新的原始 symbol, 使用带有一个可选字符串作为描述的Symbol():
var sym1 = Symbol(); var sym2 = Symbol("foo"); var sym3 = Symbol("foo");
#Symbol("foo") 不会强制字符串 “foo” 成为一个符号。
它每次都创建一个新的符号:
Symbol("foo") === Symbol("foo"); // false
#使用 new 运算符的语法将会抛出一个 TypeError 错误:
这会阻止创建一个显式的符号包装器对象而不是一个新的符号值。围绕原始数据类型创建一个显式包装器对象从 ES6 开始不再被支持。
现有的原始包装器对象,如 new Boolean、 new String以及new Number因为遗留原因仍可被创建。
var sym = new Symbol(); // TypeError
#如果非要创建一个符号包装对象(Symbol wrapper object),可以使用 Object() 函数:
var sym = Symbol("foo"); typeof sym; // "symbol" var symObj = Object(sym); typeof symObj; // "object"
全局符号注册表中的共享符号
Symbol.for()
Symbol.keyFor()
#在对象中查找符号属性
Object.getOwnPropertySymbols()
用for...in遍历不出来
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" }
#typeof运算符能帮助识别(标识)符号
Symbol type 不能转换成 number
不能 Symbol("foo") + "bar"
typeof Symbol() === 'symbol' typeof Symbol('foo') === 'symbol' typeof Symbol.iterator === 'symbol'
#JSON.stringify()
JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'
#Symbol wrapper objects as property keys(被包装成对象键值后)
var sym = Symbol("foo"); var obj = {[sym]: 1}; obj[sym]; // 1 obj[Object(sym)]; // still 1
Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols(obj)
返回一个数组,该数组包含了指定对象自身的(非继承的)所有 symbol 属性键。
和 Object.getOwnPropertyNames() 类似,但后者返回的结果只会包含字符串类型的属性键,也就是传统的属性名。
#Object.getOwnPropertySymbols()查找符号属性
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)