zoukankan      html  css  js  c++  java
  • ES6新特性:增加新类型:Symbol

      本文所有Demo的运行环境都为nodeJS, 参考:让nodeJS支持ES6的词法----babel的安装和使用 

      ES6新增了一种数据类型:SymbolSymbol是用来定义对象的唯一属性名的不二之选;

      Symbol如何使用

      Symbol如何使用呢, Symbol不是一个构造函数哦, 如果用new Symbol的话, 会报错的:

    var sym1 = Symbol();
    var sym2 = Symbol("foo");
    var sym3 = Symbol("foo");
    console.log(sym1, sym2, sym3) //输出Symbol() Symbol(foo) Symbol(foo)

      连自己都不等于自己

    //用同样的参数创建两次, 也是不相等的:
    Symbol("foo") === Symbol("foo"); //输出:false

      作为属性名的Symbol;使用Symbol给对象添加唯一的属性, Symbol也能作为对象的函数名;

    let obj = {};
    let sAttr0 = Symbol("hehe");
    let sAttr1 = Symbol("meme");
    obj[sAttr1] = 1;
    console.log(obj[sAttr1]);
    
    obj[sAttr0] = () => {
        return ++obj[sAttr0];;
    };

      我们可以用typeof判断某一个变量类型为Symbol类型:

    typeof Symbol() === 'symbol' //输出:true
    typeof Symbol('foo') === 'symbol' //输出: true
    typeof Symbol.iterator === 'symbol' //输出 : true

      如果我们不知道Symbol的实例名字是什么,我们怎么获取到Symbol值的呢, Symbol无法被for infor of循环,以及Object.keys, Object.values 等都无法遍历到Symbol的属性; Object下给我们提供了一个getOwnPropertySymbols

    let sym0 = Symbol("o_o?");
    let obj = {
        [sym0] : "heheda"
    }
    for( let prop of Object.getOwnPropertySymbols(obj) ) {
        //prop就是Symbol的名字
        console.log( obj[prop] ); //输出:heheda
    };

      或者用ES6提供的反射 : Reflect.ownKeys, 反射?

    let sym0 = Symbol("o_o?");
    let obj = {
        [sym0] : "heheda"
    }
    console.log( Reflect.ownKeys(obj) ); //输出:[ Symbol(o_o?) ]

       Symbol.for和 Symbol.keyFor

      Symbol.for和Symbol的唯一区别是 Symbol.for创建的两个实例可能相等, 根据Symbol的参数生成实例, 如果参数一样, 那么会返回同一个实例;

    let foo = Symbol.for( "1111" );
    let bar = Symbol.for("1111");
    console.log( foo === bar );  //输出: true
    //只有通过Symbol.for创建的对象,才能用keyFor找到原来的参数;
    console.log(Symbol.keyFor(foo)) //会输出:1111

      

      Symbol的属性以及这些属性的用处:

      Symbol.prototype: Symbol有指向的原型:

    console.log(Symbol.prototype); //输出Symbol的原型

      Symbol.length: Symbol的length为1, 也就是说调用Symbol需要一个参数, 当然不给参数也没啥事。

      Symbol.Iterator:对象的Symbol.Iterator属性, 指向这个对象的默认遍历器:

    var myIterable = {};
    myIterable[Symbol.iterator] = function* () {
        yield 1;
        yield 2;
        yield 3;
    };
    console.log([...myIterable]); // [1, 2, 3]

      Symbol.match:ES6中字符串去匹配对象的Symbol.match方法, 匹配的结果完全可控, 以下Demo,相当于把字符串"strstring"作为obj[Symbol.match]方法的参数, 然后返回用户设定的值, chrome和FF目前还不支持:

    let obj = {
        [Symbol.match](string) {
            console.log(string);
            return "heheda";
        }
    };;
    console.log("strstring".match(obj));

        

      Symbol.replace:和上面的道理一样:

    let obj = {
        [Symbol.replace](string) {
            console.log(string);
            return "replllll";
        }
    };
    console.log( "sssss".replace(obj) ); //输出:  sssss    replllll

      Symbol.split:和上面的道理一样。

      Symbol.toPrimitive:对象的Symbol.toPrimitive指向一个方法, 当对象转化为原始值得话, 会调用这个方法, 一个对象转为原始值由三种情况:string, number, default

        var obj1 = {};
        console.log(+obj1);     // NaN
        console.log(`${obj1}`); // "[object Object]"
        console.log(obj1 + ""); // "[object Object]"
    
        // obj2有定义Symbol.toPrimitive属性;
        var obj2 = {
            [Symbol.toPrimitive](hint) {
            if (hint == "number") {
                return 10;
            }
            if (hint == "string") {
                return "hello";
            }
            return true;
        }
        };
        console.log(+obj2);     // 10      -- 转化 为 "number"
        console.log(`${obj2}`); // "hello" -- 转化 为 "string"
        console.log(obj2 + ""); // "true"  -- 转化 为 "default"
    

      Symbol.toStringTag:Symbol.toStringTag, 这个玩意儿厉害了, 连对象的toString方法都给改了,而且用Object.prototype.toString.call这个对象 输出也是一样的, 这个情何以堪, 以后判断元素类型必须用别的方法了, 改动大了.... :

    console.log({ [Symbol.toStringTag] : "str "}.toString()); //输出:[object str ]
    console.log(Object.prototype.toString.call({ [Symbol.toStringTag] : "str "}))
    //输出:[object str ]
    class Collection { get [Symbol.toStringTag]() { return 'xxx'; } } var x = new Collection(); console.log(x.toString())// 输出:"[object xxx]"

       参考:

        mdn:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

        阮一峰ECMAScript 6 入门:http://es6.ruanyifeng.com/#docs/symbol

    作者: NONO
    出处:http://www.cnblogs.com/diligenceday/
    QQ:287101329
    微信:18101055830 

  • 相关阅读:
    csuOJ啊 1553
    Codeforces 111B【看看自己和别人在代码能力上的差距!】
    hdu1849
    hdu 1847
    校队训练赛,同时也是HDU4497(数论:素数分解+组合数学)
    POJ 2356 (抽屉原理)
    线段树总结一【转】
    训练赛(1---5)D
    训练赛(1---5)A
    HDU1556 【树状数组】(改段求点)
  • 原文地址:https://www.cnblogs.com/diligenceday/p/5462733.html
Copyright © 2011-2022 走看看