Symbol是原始类型,不能用new 创建
var s1 = Symbol('a');
typeof s1;//symbol
Symbol参数可接受字符串
表示对Symbol实例的描述,主要是为了显示时容易区分,即是接受的字符串相等,返回值也不相等。
var s1 = Symbol('a');//Symbol(a)
var s2 = Symbol('b');//Symbol(b)
s1 === s2;//false
var s3 = Symbol('a');//Symbol(a)
s1 === s3;//false
Symbol不可强制转换为string,必须显示转换
''+s1;//VM4356:1 Uncaught TypeError: Cannot convert a Symbol value to a string
at <anonymous>:1:3
s1.toString();//"Symbol(a)"
String(s1);//"Symbol(a)"
不能用.
为对象添加属性
因为.
后面必须是字符串,而Symbol不是string类型的,其typeof 返回symbol
var o = {a:1}
var s1 = Symbol('a');
o[s1] = 2;
Symbol参数为对象时调用对象的toString返回值为Symbol的参数
var obj = {
toString() {
return 'abc';
}
};
var sym = Symbol(obj);//Symbol(abc)
- 若对象的toString方法返回原始值直接使用
- 若对象的toString方法返回对象,则检查是否有valueOf,返回valueOf的返回值
- 若toString和valueOf都返回对象,则报错,
- 若同时存在toString和valueOf,且都返回原始值则使用toString优先。
var obj = {
toString() {
return {};
}
};
var sym = Symbol(obj);
Uncaught TypeError: Cannot convert object to primitive value
at Symbol
遍历
Symbol定义的属性不会出现在下面循环中:
- for in:可获取原型属性,不可获取不可枚举属性
- for of:不可遍历对象,可遍历数组
- Object.keys:原型属性和不可枚举属性都不能获取
- Object.getOwnPropertyByNames:不可获取原型属性,可获取不可枚举属性
- JSON.stringify:原型属性和不可枚举属性都不能获取
- Reflect.ownKeys:可获取不可枚举和Symbol,不可获取原型
总结:
获取原型上属性的有:for in;
获取不可枚举属性的有:getOwnPropertyNames,Reflect.ownKeys
可获取Symbol属性的有:getOwnpropertySymbols,Reflect.ownKeys
可用下面的方法取到所有symbol类型的属性,返回Array类型的Symbol属性集合
Object.getOwnPropertySymbols(obj)
或者用下面的方法取到对象上的所有属性:
var p = {w:2};
var obj = Object.create(p);
obj.a = 1;
Object.defineProperty(obj,"b",{
value:123
})
var a = Symbol('a');
var b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
Reflect.ownKeys(obj);// [Symbol(a), Symbol(b)]
可见,Reflect.ownKeys可以取到隐式属性,但不能取到继承属性。
Symbol.for
Symbol.for接收字符串为其值,然后搜索有没有以该参数为名称的Symbol值,有的话直接返回,没有的话以该参数创建Symbol,相当于登记了一个全局Symbol,可在不同iframe或者service worker中取到。
var s1 = Symbol.for('s');
var s2 = Symbol.for('s');
s1 === s2;//true
Symbol.keyFor
Symbol.KeyFor返回已经登记的Symbol类型的值。
Symbol.keyFor(s1);//s