1、为什么添加Symbol基本类型
虽然学习ES6一段时间了,但是由于工作中没有使用到,对Symbol数据类型一直没有过多了解,最近有机会学习了这方面的知识,就做了下笔记。2015年发布了ECMAScript的第六个版本,这个版本中引入了Symbol数据类型,作为JS语言的第七种基本数据类型,其中前六种是:Bolean, Null, Undefined, String, Number, Object
。为什么这个版本会引入Symbol类型,为了解决什么问题呢?
The data type "symbol" is a primitive data type having the quality that, values of this type can be used to make object properties that are anonymous.
翻译上边那段话的意思就是Symbol值可以作为对象的属性,因为每一个Symbol值都是独一无二的,所以可以避免属性冲突,这个就是Symbol的作用了。对象的属性类型在ES6之前只能是String类型,ES6之后Symbol和String类型都可以。
2、Symbol方法
Symbol()
不是一个完整的构造函数,因此不能通过new Symbol()
来创建,而是使用Symbol()
来创建一个Symbol实例,这个方法有一个可选参数用来描述symbol,该参数是字符串类型。
let sym1 = Symbol('test');
let sym2 = Symbol('test');
typeof sym1; //symbol
sym1 == sym2; //false
上段代码中,sym1和是sym2都是一个独一无二的值,虽然参数相同,却不相等。可以通过 typeof 运算符判断Symbol值的数据类型。
由于Symbol值的唯一性,意味着其可以作为对象的属性名,避免出现相同属性名,产生某一个属性被改写或覆盖的情况。Symbol值作为属性名时,需要注意两点:
let sym3 = Symbol('test');
let obj={name: 'lin', [sym3]: 'foo'};
obj[sym3]; //"foo"
JSON.stringify(obj); //"{"name":"lin"}"
Object.keys(obj); //["name"]
Object.getOwnPropertyNames(obj); //["name"]
for (let key in obj) {
console.log(key); //name
}
Object.getOwnPropertySymbols(obj); //[Symbol(test)]
- 不能通过点运算符访问,需要通过方括号访问。
- 不能通过
for...in
、for...of
遍历,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。但是它也不是私有属性,可以通过Object.getOwnPropertySymbols()
方法获取对象Symbol 属性名。
有时需要创建并访问全局的Symbol值,这就需要Symbol.for()
和Symbol.keyFor()
方法:
Symbol.for(key)
该方法有点类似单例模式,首先会检查Symbol全局注册表中有没有以key作为描述的Symbol值,如果有则返回该值,没有则新建并返回一个Symbol值,并将其加入到注册表中。Symbol.keyFor()
该方法返回已在Symbol全局注册表中登记的Symbol值得key,如果没有则返回undefined。
Symbol.for()
和Symbol()
的区别是:Symbol()
不会先在注册表中检查,每次都会创建一个新的Symbol值。
3、内置Symbol值
Symbol.hasInstance
对象的Symbol.hasInstance
属性指向一个内部方法,可以通过instanceof
调用Symbol.isConcatSpreadable
对象的Symbol.isConcatSpreadable
属性是布尔值,表示用于
Array.prototype.concat()
时,是否可以展开
3.Symbol.iterator
对象的Symbol.iterator
属性指向一个方法,for...of
语句调用
Symbol.match
对象的Symbol.hasInstance
属性指向一个方法,String.prototype.match
方法调用Symbol.specie
对象的Symbol.specie
属性指向一个构造函数,用以创建派生对象Symbol.replace
对象的Symbol.replace
属性指向一个方法,String.prototype.replace
方法调用
7.Symbol.search
对象的Symbol.search
属性指向一个方法,String.prototype.search
方法调用
8.Symbol.split
对象的Symbol.split
属性指向一个方法,String.prototype.split
方法调用
Symbol.unscopables
对象的Symbol.unscopables
属性指向一个对象。该对象指定了使用with
关键字时,哪些属性会被with环境排除Symbol.toPrimitive
对象的Symbol.toPrimitive
属性指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。Symbol.toStringTag
对象的Symbol.toStringTag
属性指向一个方法。在该对象上面调用Object.prototype.toString
方法时,如果这个属性存在,它的返回值会出现在toString
方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object]
或[object Array]
中object
后面的那个字符串。