ES5 的对象属性名都是字符串,很容易造成属性名的冲突,为了防止属性名冲突,ES6 引入了类型 Symbol
Symbol 是一种新的原始数据类型,表示独一无二的值,它是 JavaScript 语言的第 7 种数据类型,前 6 种分别是:Undefined、Null、Boolean、String、Number 和 Object
Symbol 值通过 Symbol 函数生成
let s = Symbol()
typeof s // 'symbol'
Symbol 函数前不能使用 new 命令,否则会报错。因为生成的 Symbol 是一个原始类型的值,不是对象
Symbol 函数接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示
如果参数是一个对象,就会调用该对象的 toString 方法,将其转为字符串,然后生成一个 Symbol 值
Symbol 函数的参数只是对当前 Symbol 值的描述,因此相同参数的 Symbol 函数的返回值是不相等的
Symbol 值不能和其它类型的值进行运算,否则会报错
Symbol 值可以显式转为字符串
var sym = Symbol('My')
String(sym) // 'Symbol(My)'
sym.toString() // 'Symbol(My)'
Symbol 值还可以转为布尔值,但是不能转为数值
由于每一个 Symbol 值都是不相等的,这就意味着 Symbol 值可以作为标识符用于对象的属性名,保证不会出现同名的属性
「魔法字符串」指的是,在代码中多次出现,与代码形成强耦合的某一个具体的字符串或数字。良好的代码风格,应该尽量消除魔法数字,而由含义清晰的变量代替
Symbol 就很适合消除魔法字符串
Symbol 作为属性名
- 不会出现在
for...in、for...of循环中 - 不会被
Object.keys()、Object.getOwnPropertyNames()返回 Object.getOwnPropertySymbols返回可以获取指定对象的所有Symbol属性名Reflect.ownKeys可以返回所有类型的键名,包括常规键名和Symbol键名
Symbol.for 接受一个字符串为参数,然后搜索有没有以这个参数作为名称的 Symbol 值
- 如果有,返回这个
Symbol值 - 如果没有,新建并返回一个以该字符串为名称的
Symbol值
Symbol.for 为 Symbol 值登记的名字是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值
- 对象的 Symbol.hasInstance 属性指向一个内部方法,对象使用 instanceof 运算符时会调用这个方法,判断该对象是否为某个构造函数的实例
- 对象的 Symbol.isConcaatSpreadable 属性等于一个布尔值,表示该对象使用
Array.prototype.concat()时是否可以展开
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e'); // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable]; // undefined
let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e'); // ['a', 'b', ['c', 'd'], 'e']
-
对象的 Symbol.species 属性指向当前对象的构造函数。创造实例时默认会调用这个方法,即使用这个属性返回的函数当做构造函数来创造新的实例对象
-
对象的 Symbol.match 属性指向一个函数,当执行
str.match(myObject)时,如果该属性存在,会调用它返回该方法的返回值 -
对象的 Symbol.replace 属性指向一个方法,当对象被
String.prototype.replace方法调用时会返回该方法的返回值 -
对象的 Symbol.search 属性指向一个方法,当对象被
String.prototype.search方法调用时会返回该方法的返回值 -
对象的 Symbol.split 属性指向一个方法,当对象被
String.prototype.split方法调用时会返回该方法的返回值 -
对象的 Symbol.iterator 属性指向该对象的默认遍历器方法
-
对象的 Symbol.toPrimitive 属性指向一个方法,对象被转为原始类型的值时会调用这个方法,返回该对象对应的原始类型值
- Symbol.toPrimitive 被调用时会接受一个字符串为参数,表示当前运算的模式
- Number:该场合需要转为数值
- String:该场合需要转为字符串
- Default:该场合可以转为数值,也可以转为字符串
- Symbol.toPrimitive 被调用时会接受一个字符串为参数,表示当前运算的模式
-
对象的 Symbol.toStringTag 属性指向一个方法,在对象上调用
Object.prototype.toString方法时,如果这个属性存在,其返回值会出现在 toString 方法返回的字符串中,表示对象的类型 -
对象的 Symbol.unscopables 属性指向一个对象,指定了使用 with 关键字时哪些属性会被 with 环境排除