概述
ES5对象属性名都是字符串容易造成属性名的冲突。
eg:var a = { name: 'lucy'};
a.name = 'lili';
这样就会重写属性
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。
它是javaScript的第7种语言,前六种分别是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。
let s1 = Symbol('s1');
let s2 = Symbol('s2');
console.log(s1); // Symbol(s1)
console.log(s2); // Symbol(s2)
s1 === s2; // false
let s3 = Symbol('s2');
s2 === s3; // false
注意:
- Symbol值不能与其他类型的值进行运算,否则会报错。
- Symbol值可以显示转为字符串。
- Symbol值也可以转为布尔值,但是不能转为数值
var mysym1 = Symbol('my symbol');
mysym1.toString() // 'Symbol('my symbol')'
String(mysym1) // 'Symbol('my symbol')'
var mysym2 = Symbol();
Boolean(mysym2); // true
Number(mysym2) // TypeError: Cannot convert a Symbol value to a number(…)
作为属性名的Symbol
let a = {};
let s4 = Symbol();
// 第一种写法
a[s4] = 'mySymbol';
// 第二种写法
a = {
[s4]: 'mySymbol'
}
// 第三种写法
Object.defineProperty(a, s4, {value: 'mySymbol'});
注意:Symbol值作为对象属性名时不能使用点运算符。
a.s4; // undefined
a.s4 = 'mySymbol';
a[s4] // undefined
a['s4'] // 'mySymbol'
在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号中
let s = =Symbol();
let obj = {
[s]:function (arg) {...}
}
obj[s](123)
上面代码中,如果s不放在方括号中,该属性的键名就是字符串s,而不是s所代表的Symbol值。
Symbol类型还可以定义一组常量,保证这组常量的值都是不相等的。
常量使用Symbol值最大的好处,就是其他任何值都不可能有相同的值,因此可以保证上面的switch语句会按设计的方式工作。
注意:Symbol值作为属性名时,该属性是公开属性,不是私有属性。
Symbol.for()和Symbol.keyFor()
Symbol.for()函数也可以用来生成Symbol值,但该函数有一个特殊的用处,就是可以重复使用一个Symbol值。
let s7 = Symbol.for('s7');
console.log(s7); // Symbol(s7)
s7.toString(); // "Symbol(s7)"
let s8 = Symbol.for('s8');
s7 === s8 // true
let s9 = Symbol();
Symbol.keyFor(s9); // undefined
Symbol.keyFor(s8); // "s8"
Symbol.for()函数要接受一个字符串作为参数,先搜索有没有以该参数作为名称的Symbol值,如果有,就直接返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。上面代码中,s7和s8实际上就是同一个Symbol值,所以两者是相等的。
Symbol.keyFor()函数是用来查找一个Symbol值的登记信息的,Symbol()写法没有登记机制,所以返回undefined;而Symbol.for()函数会将生成的Symbol值登记在全局环境中,所以Symbol.keyFor()函数可以查找到用Symbol.for()函数生成的Symbol值。
内置Symbol值
ES6提供了11个内置的Symbol值,分别是Symbol.hasInstance 、Symbol.isConcatSpreadable 、Symbol.species 、Symbol.match 、Symbol.replace 、Symbol.search 、Symbol.split 、Symbol.iterator 、Symbol.toPrimitive 、Symbol.toStringTag 、Symbol.unscopables 等。
更多请查看:http://es6.ruanyifeng.com/#docs/symbol