es6 symbol类型
ES5的对象属性名都是字符串,很容易造成属性名冲突。ES6引入Symbol保证每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突
创建
Symbol 值通过Symbol函数生成。这就是说,对象的属性名可以有两种类型:一种是字符串,另一种是Symbol类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突
注:Symbol函数前不能使用new命令,否则会报错。因为生成的 Symbol 是一个原始类型的值,不是对象
使用
每一个Symbol值都是不相等的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。
let s3 = Symbol();
let s4 = Symbol();
console.log('s3==s4',s3==s4);
输出:s3==s4 false
(1)Symbol 值作为对象属性名时,不能用点运算符
(2)对象内部使用symbol值定义属性时,symbol值应放在方括号中
属性检索
Symbol作为属性名,该属性不会出现在for…in、for…of循环中,也不会被Object.getOwnPropertyNames()、Object.keys()、JSON.stringify()返回。于是,在ES6中添加了一个Object.getOwnpropertySymbols()方法来检索对象中的Symbol属性
Object.getOwnPropertySymbols()方法的返回值是一个包含所有Symbol自有属性的数组
let obj1 = {};
let a1 = Symbol('a');
let b1 = Symbol('b');
obj[a1] = 'hello';
obj[b1] = 'world';
let ObjectSymbols = Object.getOwnPropertySymbols(obj);
console.log(ObjectSymbols);
另一个新的API——Reflect.ownKeys()方法可以返回所有类型的键名,包括常规键名和 Symbol 键名
共享体系
Symbol.for()
如果想创建一个可共享的Symbol,要使用Symbol.for()方法。它只接受一个参数,也就是即将创建的Symbol的字符串标识符,这个参数同样也被用作Symbol的描述
Symbol.keyFor()
还有一个与Symbol共享有关的特性:可以使用Symbol.keyFor()方法在Symbol全局注册表中检索与Symbol有关的键
let si1 = Symbol('foo');
let si2 = Symbol('foo');
console.log(si1==si2);//false
console.log(Symbol.keyFor(si1));//undefined
si1 = Symbol.for('foo');
si2 = Symbol.for('foo');
console.log(si1===si2);//true
console.log(Symbol.keyFor(si1));//foo
内置的symbol值
S6还提供了11个内置的Symbol值,指向语言内部使用的方法
1、 Symbol.haslnstance
一个在执行instanceof时调用的内部方法,用于检测对象的继承信息
2、 Symbol.isConcatSpreadable
一个布尔值,用于表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
3、Symbol.iterator
一个返回迭代器的方法
4、Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用于比较字符串
5、Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串的子串
6、Symbol.search
一个在调用String.prototype.search()方法时调用的方法,用于在字符串中定位子串
7、Symbol.species
用于创建派生类的构造函数
8、Symbol.split
一个在调用String.prototype.split()方法时调用的方法,用于分割字符串
9、Symbol.toprimitive
一个返回对象原始值的方法
10、Symbol.ToStringTag
一个在调用Object.prototype.toString()方法时使用的字符串,用于创建对象描述
11、Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合