引入symbol的原因
-
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入
Symbol
的原因。
Symbol的概念
-
ES6 引入了一种新的原始数据类型
Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。 -
Symbol是通过Symbol()函数生成;
-
let s = Symbol();
console.log(s);
console.log(typeof s);//symbol
-
-
注意,
Symbol
函数前不能使用new
命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型-
代码演示:
let s1 = Symbol('hello');
let s2 = symbol('world');
console.log(s1,s2);
console.log(s1.toString());//Symbol(hello)
-
创建Symbol的时候,添加参数,相当于给不容易分辨出来的Symbol类型添加一个描述,易于区分;
如果 Symbol 的参数是一个对象,就会调用该对象的toString
方法,将其转为字符串,然后才生成一个 Symbol 值。
代码演示:
const obj = {
toString(){
return 'hello'
}
};
const s = Symbol(obj);
console.log(s);//Symbol(hello)
用法!
①、不能进行运算
let s = Symbol();
console.log(s + 'a');//报错
②、显示调用tostring()
let s = Symbol();
console.log(s.toString());//Symbol()没什么意义,所以一般不用
③隐式类型转换--布尔值
let s = Symbol();
if(s){
console.log('隐式类型转换为true');
}else{
console.log('隐式类型转换为false')
}
④、Symbol创建的值不同
//无参数
let s1 = Symbol();
let s2 = Symbol();
console.log(s1 == s2);//false//有参数
let s3 = Symbol('hello');
let s4 = Symbol('hello');
console.log(s3 == s4);//false
不管是传参或者不传参,symbol的值都是唯一的;
遍历symbol
-
使用
Object.getOwnPropertySymbols(object)
来遍历对象,返回一个数组,数组元素由symbol组成;-
let res = Object.getOwnPropertySymbols(obj); console.log(res);//{symbol(name),symbol(age),symbol(address)symbol(test)}; res.forEach(item=>{ console.log(obj[item]); })
-
该方法只能获取symbol属性,不能获取普通属性;
-
-
使用Reflect.ownkeys(object)来遍历对象,返回一个数组,数组元素由对象中所有类型的属性组成;
-
let res = Reflect.ownKeys(obj); console.log(res);//Symbol(textFunction) res.forEach(item=>{ console.log(obj[item]); })
-