摘要:原文翻譯瘋狂的技術(shù)宅本文首發(fā)微信公眾號(hào)歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章類型檢測(cè)假設(shè)是一個(gè)數(shù)組,我們想要實(shí)現(xiàn)一些功能。將為數(shù)組返回,即使它們是在另一個(gè)中創(chuàng)建的。本文首發(fā)微信公眾號(hào)歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章
原文:https://jakearchibald.com/201...
翻譯:瘋狂的技術(shù)宅
本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章
function foo(obj) { // … }
假設(shè)obj是一個(gè)數(shù)組,我們想要實(shí)現(xiàn)一些功能。比如 JSON.stringify就是一個(gè)例子,它以不同的方式把數(shù)組輸出到其他對(duì)象。
我們可以這樣做:
if (obj.constructor == Array) // …
但是對(duì)于數(shù)組的子類來說這是錯(cuò)誤的:
class SpecialArray extends Array {} const specialArray = new SpecialArray(); console.log(specialArray.constructor === Array); // false console.log(specialArray.constructor === SpecialArray); // true
所以如果你想檢查子類的類型,那么應(yīng)該用instanceof:
console.log(specialArray instanceof Array); // true console.log(specialArray instanceof SpecialArray); // true
但是當(dāng)引入多個(gè)realm時(shí),事情將會(huì)變得更加復(fù)雜:
Multiple realmsrealm包含self引用的JavaScript全局對(duì)象。 因此,可以說在worker中運(yùn)行的代碼與在頁面中運(yùn)行的代碼處于不同的realm。 在iframe之間也是如此,但同源iframe也共享一個(gè)ECMAScript"代理",這意味著對(duì)象可以穿越 realm。
接著看代碼:
這兩個(gè)都是false,因?yàn)椋?/p>
console.log(Array === iframe.contentWindow.Array); // false
iframe有自己的數(shù)組構(gòu)造函數(shù),它與父頁面中的構(gòu)造函數(shù)不同。
Array.isArrayconsole.log(Array.isArray(arr)); // true
Array.isArray 將為數(shù)組返回true,即使它們是在另一個(gè)realm中創(chuàng)建的。 對(duì)于任何realm的Array的子類,它也會(huì)返回true。 這就是JSON.stringify內(nèi)部的處理方法。
但是,這并不意味著arr有 array 方法。 有些甚至所有方法都已設(shè)置為undefined,或者數(shù)組可能已將其整個(gè)原型刪除:
const noProtoArray = []; Object.setPrototypeOf(noProtoArray, null); console.log(noProtoArray.map); // undefined console.log(noProtoArray instanceof Array); // false console.log(Array.isArray(noProtoArray)); // true
不管怎樣,如果要杜絕上述問題,可以通過Array原型調(diào)用Array的方法:
if (Array.isArray(noProtoArray)) { const mappedArray = Array.prototype.map.call(noProtoArray, callback); // … }Symbols 與 realms
再看看這個(gè):
上面的logs 1, 2, 3 很不引人注目,但 for-of 循環(huán)通過調(diào)用arr[Symbol.iterator]來工作,這在某種程度上可以跨越realm。 這是如何做:
const iframe = document.querySelector("iframe"); const iframeWindow = iframe.contentWindow; console.log(Symbol === iframeWindow.Symbol); // false console.log(Symbol.iterator === iframeWindow.Symbol.iterator); // true
雖然每個(gè)realm都有自己的Symbol實(shí)例,但Symbol.iterator在各個(gè)realm都是相同的。
Symbols同時(shí)也是JavaScript中最獨(dú)特和最獨(dú)特的東西。
The most unique 多唯一性const symbolOne = Symbol("foo"); const symbolTwo = Symbol("foo"); console.log(symbolOne === symbolTwo); // false const obj = {}; obj[symbolOne] = "hello"; console.log(obj[symbolTwo]); // undefined console.log(obj[symbolOne]); // "hello"
傳遞給Symbol函數(shù)的字符串只是一個(gè)描述。 即使在同一realm內(nèi),這些Symbol也是獨(dú)一無二的。
The least unique 最小唯一性const symbolOne = Symbol.for("foo"); const symbolTwo = Symbol.for("foo"); console.log(symbolOne === symbolTwo); // true const obj = {}; obj[symbolOne] = "hello"; console.log(obj[symbolTwo]); // "hello"
Symbol.for(str) 創(chuàng)建一個(gè)與傳遞它的字符串唯一的symbol。 有趣的是它在各個(gè)realms都是一樣的:
const iframe = document.querySelector("iframe"); const iframeWindow = iframe.contentWindow; console.log(Symbol.for("foo") === iframeWindow.Symbol.for("foo")); // true
這就是Symbol.iterator大致的工作原理。
創(chuàng)建自己的 "is" 函數(shù)如果我們想要?jiǎng)?chuàng)建我們自己的“is”函數(shù)并跨越realm會(huì)怎么樣? 好吧,Symbol允許我們這樣做:
const typeSymbol = Symbol.for("whatever-type-symbol"); class Whatever { static isWhatever(obj) { return obj && Boolean(obj[typeSymbol]); } constructor() { this[typeSymbol] = true; } } const whatever = new Whatever(); Whatever.isWhatever(whatever); // true
即使實(shí)例來自另一個(gè)realm,即使它是一個(gè)子類,即使它的原型已被刪除,也是可以的。
唯一的問題是,你需要確認(rèn)自己的symbol名稱在所有代碼中都是唯一的。 如果其他人創(chuàng)建了他們自己的Symbol.for("whatever-type-symbol")并使用它來表示別的東西,那么isWhatever肯定返回false。
本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101233.html
摘要:當(dāng)時(shí),如果老生區(qū)大小超過設(shè)定的值時(shí),就會(huì)報(bào)錯(cuò)。一般是無限制增長(zhǎng)的數(shù)組無限制設(shè)置屬性和值大循環(huán)等出處林小新。這部分由于攻城獅并為深入,可以參考如何定位的內(nèi)存泄漏內(nèi)存泄漏以及定位 showImg(https://segmentfault.com/img/bVbnysD?w=649&h=658);↑開局一張圖,故事全靠編↑ 從一次宕機(jī)說起 這是一個(gè)很狗血的故事,故事的開頭是一個(gè)項(xiàng)目,這個(gè)項(xiàng)...
摘要:數(shù)組定義數(shù)組數(shù)組名稱元素元素定義空數(shù)組前端定義數(shù)組同時(shí)添加不同類型的元素構(gòu)造函數(shù)方式數(shù)組名稱元素,元素?cái)?shù)組名稱類型,表示數(shù)組的長(zhǎng)度存在元素的個(gè)數(shù)用創(chuàng)造出一個(gè)空數(shù)組的構(gòu)造函數(shù)前端用創(chuàng)造一個(gè)空數(shù)組的構(gòu)造函數(shù)并添加元素函數(shù)方式定義數(shù)組名稱元素,元 數(shù)組 定義數(shù)組 1.var 數(shù)組名稱 = [元素1,元素2,...]; var arr=[];//定義空數(shù)組 var arr1=[100,前端,t...
摘要:使用進(jìn)行的仿手機(jī)的的制作,在上,參考了設(shè)計(jì)師的作品,作品由個(gè)人獨(dú)立開發(fā),源碼中進(jìn)行了詳細(xì)的注釋。關(guān)于接入聊天機(jī)器人遇到的跨域問題起初,天真的以為官方應(yīng)該提供了用的接口,然而沒有找到。 使用Vue2進(jìn)行的仿手機(jī)QQ的webapp的制作,在ui上,參考了設(shè)計(jì)師kaokao的作品,作品由個(gè)人獨(dú)立開發(fā),源碼中進(jìn)行了詳細(xì)的注釋。 由于自己也是初學(xué)Vue2,所以注釋寫的不夠精簡(jiǎn),請(qǐng)見諒。 目前已實(shí)...
摘要:多個(gè)窗口意味著多個(gè)全局環(huán)境,不同的全局環(huán)境擁有不同的全局對(duì)象,從而擁有不同的內(nèi)置類型構(gòu)造函數(shù)。比如,表達(dá)式會(huì)返回,因?yàn)閷傩缘玫降膬H僅是構(gòu)造函數(shù),而且是可以被手動(dòng)更改的,只是返回的構(gòu)造函數(shù)的名字,它并不返回類名。 原文:ES6時(shí)代,你真的會(huì)克隆對(duì)象嗎(二) 上一篇,我們從Symbol和是否可枚舉以及屬性描述符的角度分析了ES6下怎么淺拷貝一個(gè)對(duì)象,發(fā)表在掘金和segmentfault上(...
摘要:在中,數(shù)組里可以容納容納中任何類型的值。方法大全在中數(shù)組是可修改的對(duì)象,每個(gè)數(shù)組都有著很多好用的方法,大多數(shù)我們?nèi)粘6紩?huì)常用。把元素添加到數(shù)組的頭部。利用使用下標(biāo)進(jìn)行操作。對(duì)當(dāng)前數(shù)組中的每一項(xiàng)運(yùn)行給定的函數(shù)返回函數(shù)結(jié)果為的項(xiàng)組成的數(shù)組。 雜談 ????數(shù)組是最簡(jiǎn)單的內(nèi)存數(shù)據(jù)結(jié)構(gòu),也是js中最常用的類型之一,整理了下我覺得應(yīng)該了解數(shù)組的相關(guān)知識(shí)。 在js中,數(shù)組里可以容納容納js中任何...
閱讀 765·2021-09-28 09:35
閱讀 2598·2019-08-29 11:25
閱讀 2160·2019-08-23 18:36
閱讀 1861·2019-08-23 16:31
閱讀 2076·2019-08-23 14:50
閱讀 3126·2019-08-23 13:55
閱讀 3296·2019-08-23 12:49
閱讀 2087·2019-08-23 11:46