美文网首页让前端飞ES6Web前端之路
ES6新加了数据类型:Symbol(2018-05-11)

ES6新加了数据类型:Symbol(2018-05-11)

作者: CRUD_科科 | 来源:发表于2018-05-16 09:53 被阅读2次

    数据类型

        在介绍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。
    

    相关文章

      网友评论

        本文标题:ES6新加了数据类型:Symbol(2018-05-11)

        本文链接:https://www.haomeiwen.com/subject/zbzxdftx.html