9.1 介绍
ES6引入Symbol作为一种新的原始数据类型,表示独一无二的值,主要是为了防止属性名冲突。
ES6之后,JavaScript一共有其中数据类型:Symbol、undefined、null、Boolean、String、Number、Object。
简单实用:
注意:
- Symbol函数不能用new,会报错。由于Symbol是一个原始类型,不是对象,所以不能添加属性,它是类似于字符串的数据类型。
- Symbol都是不相等的,即使参数相同。
- Symbol不能与其他类型的值计算,会报错。
Symbol可以显式转换为字符串:
Symbol可以转换为布尔值,但不能转为数值:
9.2 Symbol作为属性名
好处:防止同名属性,还有防止键被改写或覆盖。
需要注意: Symbol作为对象属性名时,不能用点运算符,并且必须放在方括号内。
常常还用于创建一组常量,保证所有值不相等:
9.3 应用:消除魔术字符串
魔术字符串:指代码中多次出现,强耦合的字符串或数值,应该避免,而使用含义清晰的变量代替。
常使用变量,消除魔术字符串:
使用Symbol消除强耦合,使得不需关系具体的值:
9.4 属性名遍历
Symbol作为属性名遍历,不出现在for...in、for...of循环,也不被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
Object.getOwnPropertySymbols方法返回一个数组,包含当前对象所有用做属性名的Symbol值。
另外可以使用Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。
由于Symbol值作为名称的属性不被常规方法遍历获取,因此常用于定义对象的一些非私有,且内部使用的方法。
9.5 Symbol.for()、Symbol.keyFor()
- Symbol.for()
- 用于重复使用一个Symbol值,接收一个字符串作为参数,若存在用此参数作为名称的Symbol值,返回这个Symbol,否则新建并返回以这个参数为名称的Symbol值。
Symbol() 和 Symbol.for()区别:
- Symbol.keyFor()
- 用于返回一个已使用的Symbol类型的key:
9.6 内置的Symbol值
ES6提供11个内置的Symbol值,指向语言内部使用的方法:
- 1.Symbol.hasInstance
- 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法。比如,foo instanceof Foo在语言内部,实际调用的是Foo[Symbol.hasInstance](foo)。
P是一个类,new P()会返回一个实例,该实例的Symbol.hasInstance方法,会在进行instanceof运算时自动调用,判断左侧的运算子是否为Array的实例。
- 2.Symbol.isConcatSpreadable
- 值为布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
- 3.Symbol.species
- 指向一个构造函数,在创建衍生对象时会使用,使用时需要用get取值器。
解决下面问题:
- 4.Symbol.match
- 当执行str.match(myObject),传入的属性存在时会调用,并返回该方法的返回值。
- 5.Symbol.replace 当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。
- 6.Symbol.hasInstance
- 当该对象被String.prototype.search方法调用时,会返回该方法的返回值。
- 7.Symbol.split
- 当该对象被String.prototype.split方法调用时,会返回该方法的返回值。
- 8.Symbol.iterator
- 对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器。
- 9.Symbol.toPrimitive
- 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。调用时,需要接收一个字符串参数,表示当前运算模式,运算模式有:
- Number : 此时需要转换成数值
- String : 此时需要转换成字符串
- Default : 此时可以转换成数值或字符串
- 10.Symbol.toStringTag
- 在该对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object]或[object Array]中object后面的那个字符串。
- 11.Symbol.unscopables
- 该对象指定了使用with关键字时,哪些属性会被with环境排除。
上面代码通过指定Symbol.unscopables属性,使得with语法块不会在当前作用域寻找foo属性,即foo将指向外层作用域的变量。
公众号:前端自习课