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]"
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容