Symbol 类型是 ES6 引入的一种数据类型,表示独一无二的值,是 JavaScript 语言的第七种数据类型。
javascript
目前我所了解的两个用途:java
Symbol 值建立的方法有两种,下面逐一介绍。函数
Symbol 值能经过Symbol
函数生成,要注意的是,Symbol 类型没有构造函数,即便用new Symbol()
会报错。此方法建立的 Symbol 值永远不会有相等的。
测试
let s1 = Symbol();
// let s = new Symbol(); // 错误例子
// 能够传入字符串做为参数
let s2 = Symbol('foo');
// 即便传入相同的字符串,获得的两个值仍然是不相等的
console.log(Symbol('foo') === Symbol('foo')); // false
// 经过 toString() 方法能够获取该值的字符串量
console.log(s2.toString()); // 'Symbol(foo)'
// 经过实例属性 description 能够获取描述的字符串量
console.log(s2.description); // 'foo'
复制代码
如例子中的s2
所示,Symbol()
能传入字符串值做为描述,且仅能做为描述,即便是传入相同的描述字符串,获得的值仍然不相等。
ui
使用Symbol.for()
方法能够获得一个"可能相同"的 Symbol 值,接受一个字符串做为参数(该值做为key
,经过keyFor()
方法能够获取该值),而后搜索有没有以该参数做为名称的 Symbol 值。若是有,就返回这个 Symbol 值,不然就新建并返回一个以该字符串为名称的 Symbol 值。看以下例子:spa
let s1 = Symbol.for('baz');
let s2 = Symbol.for('baz');
console.log(s1 === s2); // true
// 获取 key 值
console.log(s1.keyFor()); // 'baz'
复制代码
使用 Symbol 做为属性名时,该属性不会出如今for...in
循环中、Object.entries()
、Object.keys()
、Object.values()
(其对应的属性值)、Object.getOwnPropertyNames()
、JSON.stringify()
的返回。但它也不是私有属性。有两个方法能够获取到有关 Symbol 值的属性:Object.getOwnPropertySymbols
方法,能够获取指定对象的全部 Symbol 属性名(Symbol 类型的值,非字符串量);以及扩展运算符(...
)。下面是测试的结果:prototype
let obj = {
[Symbol()]: 'symbol',
a: 1
}
// 【for...in】
for(let i in obj){
console.log(i); // a (只有a)
}
// 【Object.entries】
let entries = Object.entries(obj);
console.log(entries); // [ [ 'a', 1 ] ]
// 【Object.values】
let values = Object.values(obj);
console.log(values); // [ 1 ]
// 【Object.keys】
let keys = Object.keys(obj);
console.log(keys); // [ 'a' ]
// 【Object.getOwnPropertyNames】
let ownPropNames = Object.getOwnPropertyNames(obj);
console.log(ownPropNames); // [ 'a' ]
// 【JSON.stringify】
console.log(JSON.stringify(obj)); // {"a":1}
// 【Object.getOwnPropertySymbols】
let ownPropSymbols = Object.getOwnPropertySymbols(obj);
console.log(ownPropSymbols); // [ Symbol() ]
// 【展开运算符(...)】
let obj2 = {...obj}
console.log(obj2); // { a: 1, [Symbol()]: 'symbol' }复制代码
以 Symbol 值做为属性名,必须使用[]
运算符定义和获取属性值。例子以下:code
let mySymbol = Symbol('foo');
let obj = {
[mySymbol]: 'Symbol',
mySymbol: 'string'
}
console.log(obj.mySymbol); // string
console.log(obj[mySymbol]); // Symbol
console.log(obj['mySymbol']); // string复制代码
ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法,当开发者须要修改指定的原生方法时会用到。下面简单列举,具体请查阅MDN文档。对象
对象的Symbol.hasInstance
属性,指向一个内部方法。当其余对象使用instanceof
运算符,判断是否为该对象的实例时,会调用这个方法。ip
对象的Symbol.isConcatSpreadable
属性等于布尔值,表示该对象用于Array.prototype.concat()
时,是否能够展开。
对象的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.toStringTag
属性,指向一个方法。在该对象上面调用Object.prototype.toString
方法时,若是这个属性存在,它的返回值会出如今toString
方法返回的字符串之中,表示对象的类型。也就是说,这个属性能够用来定制[object Object]
或[object Array]
中object
后面的那个字符串。
对象的Symbol.unscopables
属性,指向一个对象。该对象指定了使用with
关键字时,哪些属性会被with
环境排除。