摘要:是一個布爾值,用于確定當調用數組的方法時,如果傳入參數是一個數組,是否需要將這個數組拍平。與其他的屬性不同的是,并不默認出現在標準對象中。
ECMAScript 6 通過在原型鏈上定義與Symbol相關的屬性來暴露語言內部邏輯,使得開發者可以對一些語言的默認行為做配置。接下來我們來看看有哪些重要的Symbol屬性可供我們使用:
1: Symbol.hasInstance 一個在執行 instanceof 時調用的方法,用于檢測對象的繼承信息 2: Symbol.isConcatSpreadable 一個布爾值,用于表示當傳遞一個集合作為Array.prototype.concat()的參數是,是否應該將集合內的元素拍平到同一層級 3: Symbol.iterator 在迭代器和生成器那篇文章已經細講過 4: Symbol.match 一個在調用String.prototype.match()時調用的方法,用于比較字符串 5: Symbol.replace 一個在調用String.prototype.replace()時調用的方法,用于替換字符串的子串 6: Symbol.search 一個在調用String.prototype.search()時調用的方法,用于定位子串在字符串中的位置 7: Symbol.split 一個在調用String.prototype.split()時調用的方法,用于分割字符串 8: Symbol.species 用于創建派生對象的構造函數 9: Symbol.toPrimitive 一個返回對象原始值的方法 10: Symbol.toStringTag 一個在調用Object.prototype.toString()時使用的字符換,用于創建對象的描述 11: Symbol.unscopables 一個定義了一些不可被with語句引用的對象屬性名稱的對象集合
上面的屬性很多,這里會挑一些比較重要和常用的來講:
1: Symbol.hasInstance
Symbol.hasInstance用于確定對象是否為函數的實例。此方法定義在Function.prototype中,所以所有的函數都默認繼承了此方法。當我們在調用例如
obj instanceof Array;
其實等價于:
Array[Symbol.instanceof](obj);
文章開頭我們就說了這些symbol屬性是為了開發者能定制化語言的內部邏輯,那我們怎樣改寫Symbol.hasInstance的默認行為呢?這里面有一點特殊的是,為了確保Symbol.instance不會被意外地重寫,該方法是被默認定義為不可寫,不可配置,和不可枚舉。如果確定要改寫它,必須通過Object.definePropoty()方法:
function MyObject(){}; Object.defineProperty(MyObject, Symbol.hasInstance, { value: function () { return false; } }); let obj = new MyObject(); console.log(obj instanceof MyObject); // false
以上代碼,我們就重寫了Symbol.hasInstance的默認邏輯,讓它始終返回false,所以哪怕明明 obj instanceof MyObject 邏輯上應該返回true,但是結果得到false。 這個例子本身邏輯上沒有意義,甚至是錯誤地,只是想要展示一下Symbol.hasInstance的用法。
我們還也可以讓Symbol.hasInstance只是某些情況下返回true,但是一定要保證instanceof的左邊是一個對象,這樣才能觸發對Symbol.hasInstance的調用,不然instanceof總是返回false。
2: Symbol.isConcatSpreadable
Symbol.isConcatSpreadable是一個布爾值,用于確定當調用數組的concat()方法時,如果傳入參數是一個數組,是否需要將這個數組拍平??聪旅嬉欢未a:
Array.prototype[Symbol.isConcatSpreadable] = false; let result = [1, 2].concat([3, 4], 5); console.log(result);//[[1, 2], [3, 4], 5]
對比一下Symbol.isConcatSpreadable為true的情況:
Array.prototype[Symbol.isConcatSpreadable] = true; let result = [1, 2].concat([3, 4], 5); console.log(result); // [1, 2, 3, 4, 5]
ES6之前,對于concat()參數為數組的情況,默認是拍平為一個層級的。ES6提供了這個窗口,讓開發者覺得這一行為。但是這里不建議直接修改Array的Symbol.isConcatSpreadable屬性,如果真的需要修改這一屬性,可以在派生數組子類里面進行修改。
與其他的Symbol屬性不同的是,Symbol.isConcatSpreadable并不默認出現在標準對象中。在一個類數組對象中,如果我們設置Symbol.isConcatSpreadable屬性為true,當執行concat()時,類數組對象的數值型屬性也會被獨立添加到concat()的調用結果中:
let collection = { 0: "a", 1: "b", length: 2, [Symbol.isConcatSpreadable]: true }; console.log(["test"].concat(collection)); // ["test", "a", "b"]
3: Symbol.match, Symbol.replace, Symbol.search, Symbol.split
通常我們對一個字符串調用match(), replace(), search(), split()方法,它們的參數,既可以是字符串,也可以是一個正則表達式。但是它們本身內部的邏輯,我們是不能修改的。而Symbol.match, Symbol.replace, Symbol.search, Symbol.split這四個屬性,就是開放了這個窗口,讓開發者可以自行定義其內部邏輯,下面開一個Symbol.match的例子,其他三個也是一樣的:
let hasLengthOf10 = { [Symbol.match]: function (value) { return value.length === 10 ? [value] : null } }; console.log("abcdefghij".match(hasLengthOf10)); // [abcdefghij] console.log("abcdefghi".match(hasLengthOf10)); // null
4: Symbol.toPrimitive
我們知道,對象不屬于基本類型。那如果我們對對象進行一些基本類型的操作會怎樣呢?比如alert一個對象:alert(obj), 或者對對象進行數學計算:obj1 - obj2, obj3 / 4等。一般呢,這些情況下,需要將對象先轉換為基本數據類型,但是轉換的規則是什么呢?ES6提供了Symbol.toPrimitive方法給開發者,開發者可以自行定義。Symbol.toPrimitive有一個重要的參數,規范中叫做類型提示(hint)。hint為String類型,有三種可能的值:
1: "number" 當轉換場景為需要對象作為一個數字 2: "string" 當轉換場景為需要對象作為一個字符串 3: "default" 當轉換場景模棱兩可的時候
這里需要注意的是,hint是JavaScript的引擎傳入給Symbol.toPrimitive方法,開發者只需要針對它可能的三種值編寫自己的邏輯,例如:
let person = { "name": "mike", "age": 24, [Symbol.toPrimitive](hint) { switch (hint) { case "number": { return this.age; } case "string": { return this.name } case "default": { return this.age + this.name } } } }; console.log(person / 2); // 12 alert(person);// alert彈窗內容為 mike console.log(person + 100); // 24mike100
代碼console.log(person + 100)這里執行了一個加法操作,因為加法既可以用作字符串類型,也可以用作數字類型,所以這里就命中了hint為"default"的情況。
5: Symbol.toStringTag
Symbol.toStringTag定義了調用Object.prototype.toString()是返回的身份標識。例如調用:
Object.prototype.toString.call([]);// "[object Array]"
"Array"這是儲存在數組對象的Symbol.toStringTag屬性中。
一般我們自己創建的對象,如果調用以上方法,或者對象的toString()方法會得到"[object Object]"。我們可以重寫對象的Symbol.toStringTag來自定義對象調用toString()方法時得到的值:
function Person(name) { this.name = name; } Person.prototype[Symbol.toStringTag] = "Person"; let mike = new Person("mike"); console.log(Object.prototype.toString.call(mike)); // [object Person] console.log(mike.toString());// [object Person]
但是,你也可以重寫對象的toString()方法,這樣并不會對Object.prototype.toString.call()造成影響:
function Person(name) { this.name = name; } let mike = new Person("mike"); Person.prototype[Symbol.toStringTag] = "Person"; Person.prototype.toString = function () { return this.name; }; console.log(Object.prototype.toString.call(mike));// [object Person] console.log(mike.toString());// mike
以上就是所有的幾個比較重要的Symbol屬性。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106014.html
摘要:但是,前來提到的個方法都不支持屬性,為了保持原有的功能,新增了一個方法來檢索類型的屬性接下來看一下式例以上,就是關于的基本使用方法。 ES6新增了一個基本數據類型:Symbol,至此ECMAScript的基本數據類型就有了6種:字符串,數字,布爾,null,undefined,Symbol。關于Symbol,我打算寫2篇文章來提取一下比較重要的知識點,這篇是第一篇,主要講Symbol的...
摘要:它是語言的第七種數據類型,前六種是布爾值字符串數值對象。在中,根據屬性名來進行判斷。,是一個布爾值,表示該對象使用時,是否可以展開。等同于,指向該對象的默認遍歷器方法,即該對象進行循環時,會調用這個方法,返回該對象的默認遍歷器。 本文字數:3000+,閱讀時間6分鐘。 如果有理解不到位的地方,歡迎大家糾錯。如果覺得還可以,希望大家可以點個贊。 謝謝大家。 目錄 一、Symbol是什么...
摘要:先搜索全局符號注冊表,如果已有,則返回這個已存在的符號值否則,會創建一個新的符號值,并使用該鍵值將其記錄到全局符號注冊表中,然后返回這個新的符號值。 主要知識點:創建符號值、使用符號值、共享符號值、符號值轉換。檢索符號值屬性以及知名符號 showImg(https://segmentfault.com/img/bVbfWhK?w=1203&h=633); 《深入理解ES6》筆記 目錄 ...
摘要:的碼點被稱為基本字符區域。關于的介紹,我準備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數前不能使用命令,否則會報錯。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完...
閱讀 3262·2021-09-22 16:06
閱讀 3254·2021-09-02 15:40
閱讀 640·2019-08-30 15:54
閱讀 1045·2019-08-26 12:22
閱讀 1384·2019-08-26 12:17
閱讀 2750·2019-08-26 12:09
閱讀 511·2019-08-26 10:20
閱讀 794·2019-08-23 16:28