ES6学习笔记--Symbol

创建符号值

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]"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容