美文网首页
ES6学习笔记--Symbol

ES6学习笔记--Symbol

作者: 牙哥 | 来源:发表于2016-12-27 12:05 被阅读29次

    创建符号值

    Symbol没有字面量形式,这在JS的基本类型中是独一无二的.可以用全局函数来创建符号值

    let firstName=Symbol();
    let person={};
    person[firstName]='Polo';
    console.log(person[firstName]); // 'Polo'
    
    //es6扩展了typeof运算符,可以识别symbol基本类型
    console.log(typeof firstName); // 'symbol;
    

    符号值是基本类型,因此调用new Symbol()会抛出错误

    共享符号值

    使用Symbol.for方法,创建共享符号值,该方法仅接受当字符串类型的参数,作为目标符号值得标识符,同时此参数也会成为该符号的描述信息

    let uid=Symbol.for('uid');
    let obj={};
    obj[uid]=12334;
    console.log(obj[uid]); // 12334
    console.log(uid);      // symbol(uid)
    

    Symbol.for() 方法首先会搜索全局符号注册表,看是否存在一个键值为 "uid" 的符号值。若是,该方法会返回这个已存在的符号值;否则,会创建一个新的符号值,并使用该键值将其记录到全局符号注册表中,然后返回这个新的符号值。这就意味着此后使用同一个键值去调用 Symbol.for() 方法都将会返回同一个符号值,就像下面这个例子:

    let uid=Symbol.for('uid');
    let obj={};
    obj[uid]=12334;
    let uid2=Symbol.for('uid');
    console.log(uid===uid2);    //true
    console.log(obj[uid2]);     //12334
    console.log(uid2);          //symbol(uid)
    

    Symbol.keyFor方法,在全局符号注册表中根据符号值检索出对应的键值

    let uid = Symbol.for("uid");
    console.log(Symbol.keyFor(uid));    // "uid"
    

    检索符号属性

    Object.keys()返回对象所有可枚举属性名称

    Object.getOwnPropertyNames() 返回所有属性名称而无视其是否可枚举

    然而以上两个方法都不能返回符号类型的属性,

    ES6中新增Object.getOwnPropertySymbols(),返回符号类型的属性

    ES6知名符号

    ES6 定义了“知名符号”来代表 JS 中一些公共行为,而这些行为此前被认为只能是内部操作。每一个知名符号都对应全局 Symbol 对象的一个属性

    这些知名符号是:

    • Symbol.hasInstance :供 instanceof 运算符使用的一个方法,用于判断对象继承关系。
    • Symbol.isConcatSpreadable :一个布尔类型值,在集合对象作为参数传递给
    • Array.prototype.concat() 方法时,指示是否要将该集合的元素扁平化。
    • Symbol.iterator :返回迭代器(参阅第七章)的一个方法。
    • Symbol.match :供 String.prototype.match() 函数使用的一个方法,用于比较字符串。
    • Symbol.replace :供 String.prototype.replace() 函数使用的一个方法,用于替换子字符串。
    • Symbol.search :供 String.prototype.search() 函数使用的一个方法,用于定位子字符串。
    • Symbol.species :用于产生派生对象(参阅第八章)的构造器。
    • Symbol.split :供 String.prototype.split() 函数使用的一个方法,用于分割字符串。
    • Symbol.toPrimitive :返回对象所对应的基本类型值的一个方法。
    • Symbol.toStringTag :供 String.prototype.toString() 函数使用的一个方法,用于创建对象的描述信息。
    • Symbol.unscopables :一个对象,该对象的属性指示了哪些属性名不允许被包含在 with 语句中。

    Symbol.hasInstance

    用于判断指定对象是否为本函数的一个实例。这个方法定义在 Function.prototype 上,因此所有函数都继承了面对 instanceof 运算符时的默认行为。 Symbol.hasInstance 属性自身是不可写入、不可配置、不可枚举的,从而保证它不会被错误地重写。

    obj instanceof Array;
    //等价于
    Array[Symbol.hasInstance](obj);
    

    ES6 从本质上将 instanceof 运算符重定义为上述方法调用的简写语法.

    例如,假设你想定义一个函数,使得任意对象都不会被判断为该函数的一个实例,你可以采用硬编码的方式让该函数的 Symbol.hasInstance 方法始终返回 false

    function MyObj(){
    }
    Object.defineProperty(MyObj,Symbol.hasInstance,{
        value:function(v){
            return false;
        }
    });
    let obj=new MyObj();
    console.log(obj instanceof MyObj);  // false
    

    Symbol.isConcatSpreadable

    该属性是一个布尔类型的属性,它表示目标对象拥有长度属性与数值类型的键、并且数值类型键所对应的属性值在参与 concat() 调用时需要被分离为个体。它只出现在特定类型的对象上,用来标示该对象在作为 concat() 参数时应如何工作,从而有效改变该对象的默认行为。

    let collection = {
        0: "Hello",
        1: "world",
        length: 2,
        [Symbol.isConcatSpreadable]: true
    };
    
    let messages = [ "Hi" ].concat(collection);
    
    console.log(messages.length);    // 3
    console.log(messages);           // ["hi","Hello","world"]
    

    Symbol.toPrimitive

    该属性规定了在对象被转换为基本类型值的时候会发生什么。

    当需要转换时, Symbol.toPrimitive 会被调用,并按照规范传入一个提示性的字符串参数。该参数有 3 种可能:

    • 当参数值为 "number" 的时候, Symbol.toPrimitive 应当返回一个数值;
    • 当参数值为 "string" 的时候,应当返回一个字符串;
    • 而当参数为 "default" 的时候,对返回值类型没有特别要求。
    function Temperature(degrees) {
        this.degrees = degrees;
    }
    
    Temperature.prototype[Symbol.toPrimitive] = function(hint) {
    
        switch (hint) {
            case "string":
                return this.degrees + "\u00b0"; // 温度符号
    
            case "number":
                return this.degrees;
    
            case "default":
                return this.degrees + " degrees";
        }
    };
    
    let freezing = new Temperature(32);
    
    console.log(freezing + "!");            // "32 degrees!"
    console.log(freezing / 2);              // 16
    console.log(String(freezing));          // "32°"
    

    Symbol.toStringTag

    该属性定义了Object.prototype.toString.call()被调用时应该返回什么值,同样可以在自定义对象上定该属性值.

    function Person(name) {
        this.name = name;
    }
    
    Person.prototype[Symbol.toStringTag] = "Person";
    
    let me = new Person("Nicholas");
    
    console.log(me.toString());                         // "[object Person]"
    console.log(Object.prototype.toString.call(me));    // "[object Person]"
    

    相关文章

      网友评论

          本文标题:ES6学习笔记--Symbol

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