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