ES6之新增数据类型Symbol知识点总结(三)
ES6的学习,主要是跟着阮一峰大神的ES6第三版这本书学的,所以我在这里主要是把知识梳理一遍,方便自己的理解记忆以及日后的再学习使用,如果想要了解更多的建议到http://es6.ruanyifeng.com/#docs/symbol看详细版的
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,它是js语言的第七种数据类型
Symbol值通过Symbol函数生成。也就是说,对象的属性名,现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型,凡是属性名属于Symbol类型,就都是独一无二的。可以保证不会与其他属性名产生冲突。
注意:Symbol函数前面不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象,也就是说,由于Symbol值不是对象,所以不能添加属性,基本上,它是一种类似于字符串的数据类型。
Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示或者转为字符串时比较容易区分,另外如果Symbol的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个Symbol值
let s1 = Symbol();
let s2 = Symbol();
console.log(s1===s2);//false
let s3 = Symbol('sy');
let s4 = Symbol('sy');
console.log(s3==s4);
从上面的实例中我们可以发现,Symbol函数的参数知识表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的
Symbol的值不能与其他类型的值进行运算,会报错,但是Symbol值可以显式转为字符串和布尔值,但不能转为数值
let s3 = Symbol('sy');
let s4 = Symbol('a');
let s = s3.toString();
console.log( typeof s);//string
// let a = s3+ s;//TypeError: Cannot convert a Symbol value to a string
let boo = Boolean(s3);
console.log(boo);//true
// let num = Number(s3);//Cannot convert a Symbol value to a number
作为对象属性名的Symbol
嗯、下面是正确的写法
let sym = Symbol();
let a={};
a[sym] = 'leo';
let b = {[sym]:'leo'};
再看一种错误的写法
let sym = Symbol();
let a={};
a.sym = 'leo';
console.log(a[sym]);//undefined
console.log(a['sym']);//leo
所以从上面的实例中可以看出:Symbol值作为对象属性名时,不能用点运算符,因为点运算符后面总是字符串,所以不会读取Symbol作为标识名所指的那个值,导致对象的属性名实际上是一个字符串,而不是一个Symbol值。同理,在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中
注意:Symbol类型值作为属性名时,该属性还是公开属性,不是私有属性
另外,Symbol类型还可以用于定义一组常量,保证这组常量的值都是不相等的。
属性的遍历:
Symbol作为属性名,该属性不会出现在for…in,for…of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、Json.stringify()返回。但是,它也不是私有属性。
let a={
[Symbol('a')]:12,
[Symbol('b')]:'aa',
[Symbol('c')]:true,
[Symbol('d')]:[1,2],
"a":123,
"boo":false
};
for(let i in a){
console.log(i);
}//a,boo
有一个Object.getOwnPropertySymbols方法可以获取指定对象的所有Symbol属性名
Object.getOwnPropertySymbols方法返回一个数组,成员是当前对象的所有用作属性名的Symbol值
let a={
[Symbol('a')]:12,
[Symbol('b')]:'aa',
[Symbol('c')]:true,
[Symbol('d')]:[1,2],
"a":123,
"boo":false
};
let arr = Object.getOwnPropertySymbols(a);
console.log(arr);//[Symbol(a), Symbol(b), Symbol(c), Symbol(d)]
另一个新的API,Reflect.ownkeys()方法可以返回所有类型的键名,包括常规键名和Symbol键名
let a={
[Symbol('a')]:12,
[Symbol('b')]:'aa',
[Symbol('c')]:true,
[Symbol('d')]:[1,2],
"a":123,
"boo":false
};
let arr=Reflect.ownKeys(a);
console.log(arr);//["a", "boo", Symbol(a), Symbol(b), Symbol(c), Symbol(d)]
Symbol for(),Symbol keyFor()
Symbol.for(),接收一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值,如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值,注意Symbol.for()会被登记在全局环境中供搜索,Symbol()不会
Symbol.keyFor():该方法返回一个已登记的Symbol类型值的key
let a= Symbol('a')
let b= Symbol.for('b');
let c= Symbol.for("b");
let d= Symbol('d');
console.log(b==c);//true
console.log(a==d);//false
console.log(Symbol.keyFor(c));//b
console.log(Symbol.keyFor(d));//undefined
从上面的实例中可以看出:变量d属于未登记的 Symbol 值,所以返会undefined。
需要注意的是,Symbol.for()为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
还没有评论,来说两句吧...