日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

浅谈 instanceof 和 typeof 的实现原理

發(fā)布時(shí)間:2025/6/16 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈 instanceof 和 typeof 的实现原理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

typeof 實(shí)現(xiàn)原理

typeof 一般被用于判斷一個(gè)變量的類型,我們可以利用 typeof 來(lái)判斷number, string, object, boolean, function, undefined, symbol 這七種類型,這種判斷能幫助我們搞定一些問(wèn)題,比如在判斷不是 object 類型的數(shù)據(jù)的時(shí)候,typeof能比較清楚的告訴我們具體是哪一類的類型。但是,很遺憾的一點(diǎn)是,typeof 在判斷一個(gè) object的數(shù)據(jù)的時(shí)候只能告訴我們這個(gè)數(shù)據(jù)是 object, 而不能細(xì)致的具體到是哪一種 object, 比如?

let s = new String('abc'); typeof s === 'object'// true s instanceof String // true 復(fù)制代碼

要想判斷一個(gè)數(shù)據(jù)具體是哪一種 object 的時(shí)候,我們需要利用 instanceof 這個(gè)操作符來(lái)判斷,這個(gè)我們后面會(huì)說(shuō)到。

來(lái)談?wù)勱P(guān)于 typeof 的原理吧,我們可以先想一個(gè)很有意思的問(wèn)題,js 在底層是怎么存儲(chǔ)數(shù)據(jù)的類型信息呢?或者說(shuō),一個(gè) js 的變量,在它的底層實(shí)現(xiàn)中,它的類型信息是怎么實(shí)現(xiàn)的呢?

其實(shí),js 在底層存儲(chǔ)變量的時(shí)候,會(huì)在變量的機(jī)器碼的低位1-3位存儲(chǔ)其類型信息?

  • 000:對(duì)象
  • 010:浮點(diǎn)數(shù)
  • 100:字符串
  • 110:布爾
  • 1:整數(shù)

but, 對(duì)于 undefined 和 null 來(lái)說(shuō),這兩個(gè)值的信息存儲(chǔ)是有點(diǎn)特殊的。

null:所有機(jī)器碼均為0

undefined:用 ?2^30 整數(shù)來(lái)表示

所以,typeof 在判斷 null 的時(shí)候就出現(xiàn)問(wèn)題了,由于 null 的所有機(jī)器碼均為0,因此直接被當(dāng)做了對(duì)象來(lái)看待。

然而用 instanceof 來(lái)判斷的話?

null instanceof null // TypeError: Right-hand side of 'instanceof' is not an object 復(fù)制代碼

null 直接被判斷為不是 object,這也是 JavaScript 的歷史遺留bug,可以參考typeof。

因此在用 typeof 來(lái)判斷變量類型的時(shí)候,我們需要注意,最好是用 typeof 來(lái)判斷基本數(shù)據(jù)類型(包括symbol),避免對(duì) null 的判斷。

還有一個(gè)不錯(cuò)的判斷類型的方法,就是Object.prototype.toString,我們可以利用這個(gè)方法來(lái)對(duì)一個(gè)變量的類型來(lái)進(jìn)行比較準(zhǔn)確的判斷

Object.prototype.toString.call(1) // "[object Number]"Object.prototype.toString.call('hi') // "[object String]"Object.prototype.toString.call({a:'hi'}) // "[object Object]"Object.prototype.toString.call([1,'a']) // "[object Array]"Object.prototype.toString.call(true) // "[object Boolean]"Object.prototype.toString.call(() => {}) // "[object Function]"Object.prototype.toString.call(null) // "[object Null]"Object.prototype.toString.call(undefined) // "[object Undefined]"Object.prototype.toString.call(Symbol(1)) // "[object Symbol]" 復(fù)制代碼

instanceof 操作符的實(shí)現(xiàn)原理

之前我們提到了 instanceof 來(lái)判斷對(duì)象的具體類型,其實(shí) instanceof 主要的作用就是判斷一個(gè)實(shí)例是否屬于某種類型

let person = function () { } let nicole = new person() nicole instanceof person // true 復(fù)制代碼

當(dāng)然,instanceof 也可以判斷一個(gè)實(shí)例是否是其父類型或者祖先類型的實(shí)例。

let person = function () { } let programmer = function () { } programmer.prototype = new person() let nicole = new programmer() nicole instanceof person // true nicole instanceof programmer // true 復(fù)制代碼

這是 instanceof 的用法,但是 instanceof 的原理是什么呢?根據(jù) ECMAScript 語(yǔ)言規(guī)范,我梳理了一下大概的思路,然后整理了一段代碼如下

function new_instance_of(leftVaule, rightVaule) { let rightProto = rightVaule.prototype; // 取右表達(dá)式的 prototype 值leftVaule = leftVaule.__proto__; // 取左表達(dá)式的__proto__值while (true) {if (leftVaule === null) {return false; }if (leftVaule === rightProto) {return true; } leftVaule = leftVaule.__proto__ } } 復(fù)制代碼

其實(shí) instanceof 主要的實(shí)現(xiàn)原理就是只要右邊變量的 prototype 在左邊變量的原型鏈上即可。因此,instanceof 在查找的過(guò)程中會(huì)遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,如果查找失敗,則會(huì)返回 false,告訴我們左邊變量并非是右邊變量的實(shí)例。

看幾個(gè)很有趣的例子

function Foo() { }Object instanceof Object // true Function instanceof Function // true Function instanceof Object // true Foo instanceof Foo // false Foo instanceof Object // true Foo instanceof Function // true 復(fù)制代碼

要想全部理解 instanceof 的原理,除了我們剛剛提到的實(shí)現(xiàn)原理,我們還需要知道 JavaScript 的原型繼承原理。

關(guān)于原型繼承的原理,我簡(jiǎn)單用一張圖來(lái)表示

我們知道每個(gè) JavaScript 對(duì)象均有一個(gè)隱式的 __proto__ 原型屬性,而顯式的原型屬性是 prototype,只有 Object.prototype.__proto__ 屬性在未修改的情況下為 null 值。根據(jù)圖上的原理,我們來(lái)梳理上面提到的幾個(gè)有趣的 instanceof 使用的例子。

  • Object instanceof Object

    由圖可知,Object 的 prototype 屬性是 Object.prototype, 而由于 Object 本身是一個(gè)函數(shù),由 Function 所創(chuàng)建,所以 Object.__proto__ 的值是 Function.prototype,而 Function.prototype 的 __proto__ 屬性是 Object.prototype,所以我們可以判斷出,Object instanceof Object 的結(jié)果是 true 。用代碼簡(jiǎn)單的表示一下

    leftValue = Object.__proto__ = Function.prototype; rightValue = Object.prototype; // 第一次判斷 leftValue != rightValue leftValue = Function.prototype.__proto__ = Object.prototype // 第二次判斷 leftValue === rightValue // 返回 true 復(fù)制代碼

    Function instanceof Function 和 Function instanceof Object 的運(yùn)行過(guò)程與 Object instanceof Object 類似,故不再詳說(shuō)。

  • Foo instanceof Foo

    Foo 函數(shù)的 prototype 屬性是 Foo.prototype,而 Foo 的 __proto__ 屬性是 Function.prototype,由圖可知,Foo 的原型鏈上并沒(méi)有 Foo.prototype ,因此 Foo instanceof Foo 也就返回 false 。

    我們用代碼簡(jiǎn)單的表示一下

    leftValue = Foo, rightValue = Foo leftValue = Foo.__proto = Function.prototype rightValue = Foo.prototype // 第一次判斷 leftValue != rightValue leftValue = Function.prototype.__proto__ = Object.prototype // 第二次判斷 leftValue != rightValue leftValue = Object.prototype = null // 第三次判斷 leftValue === null // 返回 false 復(fù)制代碼
  • Foo instanceof Object

    leftValue = Foo, rightValue = Object leftValue = Foo.__proto__ = Function.prototype rightValue = Object.prototype // 第一次判斷 leftValue != rightValue leftValue = Function.prototype.__proto__ = Object.prototype // 第二次判斷 leftValue === rightValue // 返回 true 復(fù)制代碼
  • Foo instanceof Function

    leftValue = Foo, rightValue = Function leftValue = Foo.__proto__ = Function.prototype rightValue = Function.prototype // 第一次判斷 leftValue === rightValue // 返回 true 復(fù)制代碼

總結(jié)

簡(jiǎn)單來(lái)說(shuō),我們使用 typeof 來(lái)判斷基本數(shù)據(jù)類型是 ok 的,不過(guò)需要注意當(dāng)用 typeof 來(lái)判斷 null 類型時(shí)的問(wèn)題,如果想要判斷一個(gè)對(duì)象的具體類型可以考慮用 instanceof,但是 instanceof 也可能判斷不準(zhǔn)確,比如一個(gè)數(shù)組,他可以被 instanceof 判斷為 Object。所以我們要想比較準(zhǔn)確的判斷對(duì)象實(shí)例的類型時(shí),可以采取 Object.prototype.toString.call 方法。

總結(jié)

以上是生活随笔為你收集整理的浅谈 instanceof 和 typeof 的实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 小镇姑娘国语版在线观看免费 | 国产又粗又猛又爽又 | 91精品在线播放 | 在线高清观看免费观看 | 涩涩网站在线 | 91天堂在线视频 | 国产一级大片在线观看 | 国产v片| 中文字幕精品一二三四五六七八 | 成人在线观看18 | 日本人妻一区二区三区 | 亚洲一区国产 | 黄色一级免费 | 亚洲国产99| 亚洲精品乱码久久久久久自慰 | av播放在线 | 日韩区一区二 | 国产高清一 | 秋霞一区| 丰满少妇在线观看资源站 | 美女视频国产 | 午夜精品视频 | 午夜影院操 | 欧美日韩网 | 欧美天堂网站 | 涩涩亚洲| 密臀久久 | 青青草视频免费播放 | 少妇被黑人到高潮喷出白浆 | 黄色视屏在线播放 | 91精品国产免费 | 超碰在线播放97 | 国产91一区二区三区 | 超碰成人免费在线 | 色 综合 欧美 亚洲 国产 | 日本高清视频在线观看 | 欧美三p | 免费精品在线观看 | 国产欧美日韩一区 | 日韩 欧美 国产 综合 | 蜜桃av噜噜一区二区三区 | 激情视频区 | av一卡| 少妇视频一区二区三区 | 国产精品无码中文字幕 | jizz日本在线 | 舌奴调教日记 | 六月色婷 | 久久久久久国 | 黄a网站| 国产v亚洲v天堂无码久久久 | 性欧美久久久 | 中文字幕在线视频不卡 | 男人晚上看的视频 | www.99视频 | 奶波霸巨乳一二三区乳 | 久久在线 | 欧美性网址 | 精品色哟哟 | 乱妇乱女熟妇熟女网站 | 麻豆小视频 | a一级网站 | 欧美日韩成人在线播放 | av观看网址 | 久久精品国产亚洲7777 | 精品+无码+在线观看 | 大香依人 | 午夜欧美福利 | 国产99在线播放 | 丰满少妇高潮在线观看 | 三级全黄视频 | 亚洲自拍第三页 | 免费看的黄色小视频 | 美女喷液视频 | 少妇精品视频一区二区 | 欧美成人一二三 | 中文字幕少妇在线三级hd | 久久加久久 | 毛片基地免费观看 | 精品人妻一区二区三区香蕉 | 日本体内she精高潮 男女视频在线免费观看 | 欧洲做受高潮欧美裸体艺术 | 日韩大片在线观看 | 色屁屁www | 粉嫩精品久久99综合一区 | 午夜不卡久久精品无码免费 | 国产午夜精品在线观看 | 欧美一卡| 中文字幕亚洲乱码熟女1区2区 | 波多野结衣在线视频免费观看 | 久色视频在线观看 | 亚洲综合图色40p | 欧美骚视频 | 国产精品宾馆在线精品酒店 | 潘金莲一级淫片aaaaaa播放 | 久久夜色网 | 日本一本高清视频 | 99一级片| 久久久国产一区二区 |