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