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