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]"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容