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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞