ES6新加了数据类型:Symbol(2018-05-11)
数据类型
在介绍Symbol之前,我们简单介绍一下JavaScript的数据类型:
JavaScript有6中数据类型,分别是:
String 字符串类型Number 数字类型Object 对象类型Boolean 布尔值类型 Null 空值 Undefined 未定义
设计Symbol的初衷是为了解决对象属性名重复
//定义一个symbol类型的变量 let sm = Symbol(); console.log(sm); //打印结果:Symbol() console.log(typeof sm); //打印结果:symbol
我们用一个Symbol( )函数来创建一个symbol类型的变量,我们打印了一下变量sm,得到的结果是控制台输出:Symbol( ),它代表着一个独一无二的值,虽然我们看不到它长什么样子,但基本上,它有点类似字符串。如何判断他是独一无二的呢?
let sm1 = Symbol(); let sm2 = Symbol(); sm1 === sm2 //结果:false console.log(sm1);//结果:Symbol() console.log(sm2);//结果:Symbol()
看起来是一样的,但是实际上是不一样的,如何让他看起来不一样的呢?
let sm1 = Symbol('sm1'); let sm2 = Symbol('sm2'); console.log(sm1); //结果:Symbol(sm1) console.log(sm2); //结果:Symbol(sm2)
用字符串sm1和sm2作为参数,结果打印出来的变量sm1和sm2就是Symbol(sm1)和Symbol(sm2),等于加上了描述,很容易区分出来。
需要注意的是,即使参数一样,描述一样,得到的两个值也是不相等的:
let sm1 = Symbol('sm'); let sm2 = Symbol('sm'); sm1 === sm2 //结果:false
当symbol值作为对象的属性名的时候,不能用点运算符获取对应的值。
let name = Symbol(); let person = { [name]:"张三" }; console.log(person[name]); //结果:张三 console.log(person.name); //结果:undefined //第一种用中括号的形式[ name ]能正确获取到,第二种用点运算符的形式,获取失败。
属性名的遍历
当symbol类型的值作为属性名的时候,该属性是不会出现在for...in和for...of中的,也不会被Object.keys( )获取到。
//定义一个symbol类型的变量name let name = Symbol(); //定义一个含有两种类型属性的对象 let person = { [name]:"张三", //symbol类型 "age":12 //string类型 }; Object.keys(person);//结果:["age"] for(let key in person){ console.log(key); } //打印结果:age //symbol类型和string字符串类型,我们通过keys( )函数获取到的属性,只有属性age
getOwnPropertySymbols( )函数 获取symbol的key值
Object.getOwnPropertySymbols( ),它会找到symbol类型的属性并且返回一个数组,数组的成员就是symbol类型的属性值
//定义两个symbol类型的变量name,age let name = Symbol("name"); let age = Symbol("age"); let person = { [name]:"张三", //symbol类型 [age]:12 //symbol类型 }; Object.getOwnPropertySymbols(person); //结果:[Symbol(name), Symbol(age)]
Reflect.ownKeys( )函数
获取所有类型的属性,不管它是字符串类型还是symbol类型
//定义一个对象,含有两种类型的属性
let person = { [Symbol('name')]:"张三", "age": 21};Reflect.ownKeys(person);//结果:["age",Symbol(name)]
Symbol.for( )函数
根据参数名,去全局环境中搜索是否有以该参数为名的symbol值,有就返回它,没有就以该参数名来创建一个新的symbol值。
let n1 = Symbol.for('name');let n2 = Symbol.for('name');console.log(n1 === n2);//结果:true
Symbol.for( )创建的symbol值会被登记在全局环境中,供以后用Symbol.for( )来搜索,而Symbol( )创建的变量就没有这样的效果了。
let n1 = Symbol('name');let n2 = Symbol.for('name');console.log(n1 === n2);//结果:false
第一行我们用Symbol( )来创建的一个symbol值,按照上述的所说的,它不会被登记在全局环境中;所以,第二行我们用Symbol.for( )去找的时候,是找不到的,找不到怎么办?此时Symbol.for( )会自动创建一个新的symbol值,也就是说n1,n2是不同的两个symbol值了,所以进行全相等比较的时候,会返回:false。
Symbol.keyFor( )函数
返回一个以被登记在全局环境中的symbol值的key,没有就返回undefined。注意这句话的一个关键词:“被登记在全局环境中”,也就是说这个symbol值是被Symbol.for( )创建的,不是被Symbol( )创建的。
let n1 = Symbol.for('name');Symbol.KeyFor(n1);//结果:name
上面的变量n1是被Symbol.for( )创建,不是被Symbol( )创建的,所以用Symbol.keyFor( )去找,是能找到的,会返回这个symbol值的key,也就是它的描述:name。
let n1 = Symbol('name'); Symbol.KeyFor(n1); //结果:undefined //1、Symbol( )创建symbol值不会被登记在全局环境中供Symbol.for( )和Symbol.keyFor( )搜索; //2、Symbol.keyFor( )函数在全局环境中找不到对应的symbol,就回返回undefined。
作者:a小磊_
链接:https://www.jianshu.com/p/f74e4e2d1a12
共同学习,写下你的评论
评论加载中...
作者其他优质文章