# Symbol ES6
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
# Symbol函数的参数
Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。
// 没有参数的情况 var s1 = Symbol(); var s2 = Symbol(); s1 === s2 // false // 有参数的情况 var s3 = Symbol('fun'); var s4 = Symbol('fun'); s3 === s4 // false
Copied!
# 作为属性名的Symbol
每一个Symbol值都是不相等的,所以Symbol值可以作为标识符。
当用于对象的属性名时,可以保证不会出现同名的属性,防止某一个键被不小心改写或覆盖。
对象属性名是Symbol值时,不能用点运算符。
var mySymbol1 = Symbol() var mySymbol2 = Symbol() var mySymbol3 = Symbol() var a = {} a[mySymbol1] = 'hello!'; var b = { [mySymbol2]:'hello!' } var c = {}; Object.defineProperty(c, mySymbol3, { value: 'hello!'}); console.log(a[mySymbol1]); //hello! console.log(b[mySymbol2]); //hello! console.log(c[mySymbol3]); //hello! var mySymbol = Symbol(); var a = {}; a.mySymbol = 'Hello!'; a[mySymbol] // undefined a['mySymbol'] // "Hello!"
Copied!
# Symbol最为属性名遍历
- 使用Symbol作为属性名时,该属性将不会被 for...in 遍历,不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
- 使用 Symbol 作为属性名时,该属性可以通过 Object.getOwnPropertySymbols() 方法获取。
- 使用 Symbol 作为属性名时,该属性不是私有属性。
# Symbol的方法
# Symbol.for()
有时,我们希望重新使用同一个Symbol值,Symbol.for方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。
Symbol.for()与Symbol()这两种写法,都会生成新的Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。
var foo = Symbol('foo'); var s1 = Symbol.for('foo'); var s2 = Symbol.for('foo'); console.log(foo); //Symbol(foo) console.log(typeof foo); //symbol console.log(s1); //Symbol(foo) console.log(typeof s1); //symbol console.log(s2); //Symbol(foo) console.log(typeof s2); //symbol console.log(foo === s1); // false console.log(s1 === s2); //true
Copied!
# Symbol.keyFor()
Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。
var s1 = Symbol.for("foo"); Symbol.keyFor(s1) // "foo" var s2 = Symbol("foo"); Symbol.keyFor(s2) // undefined
Copied!
# Symbol的应用场景
- 在对象中有很多值,但是循环输出时,并不希望全部输出,那我们就可以使用Symbol进行保护。
- 解决属性名的冲突,因为传入对象属性时,同样的Symbol不相等;
解释:什么是冲突呢?当多人合作编码的时候,经常会出现你往对象上加了一个某某属性(比如 $ ),他人正好也想到了这个名称,当你们同时用了这个名称作为属性,代码之间就会发生冲突,互相覆盖。而用 symbol,即使都用了相同的描述,也不是同一个 symbol。 - Symbol值不能与其他类型的值进行运算,会报错。