菜鳥也能搞懂js中typeof與instanceof區(qū)別
一、typeof
typeof 操作符返回一個(gè)字符串,表示未經(jīng)計(jì)算的操作數(shù)的類型
使用方法如下:
typeof operand typeof(operand)
operand表示對象或原始值的表達(dá)式,其類型將被返回
舉個(gè)例子
typeof 1 // 'number' typeof '1' // 'string' typeof undefined // 'undefined' typeof true // 'boolean' typeof Symbol() // 'symbol' typeof null // 'object' typeof [] // 'object' typeof {} // 'object' typeof console // 'object' typeof console.log // 'function'
從上面例子,前6個(gè)都是基礎(chǔ)數(shù)據(jù)類型。雖然typeof null為object,但這只是 JavaScript 存在的一個(gè)悠久 Bug,不代表null 就是引用數(shù)據(jù)類型,并且null 本身也不是對象
所以,null 在 typeof 之后返回的是有問題的結(jié)果,不能作為判斷null的方法。如果你需要在 if 語句中判斷是否為 null,直接通過===null來判斷就好
同時(shí),可以發(fā)現(xiàn)引用類型數(shù)據(jù),用typeof來判斷的話,除了function會被識別出來之外,其余的都輸出object
如果我們想要判斷一個(gè)變量是否存在,可以使用typeof:(不能使用if(a), 若a未聲明,則報(bào)錯(cuò))
if(typeof a != 'undefined'){ //變量存在 }
二、instanceof
instanceof 運(yùn)算符用于檢測構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在某個(gè)實(shí)例對象的原型鏈上
使用如下:
object instanceof constructor
object為實(shí)例對象,constructor為構(gòu)造函數(shù)
構(gòu)造函數(shù)通過new可以實(shí)例對象,instanceof 能判斷這個(gè)對象是否是之前那個(gè)構(gòu)造函數(shù)生成的對象
// 定義構(gòu)建函數(shù) let Car = function() {} let benz = new Car() benz instanceof Car // true let car = new String('xxx') car instanceof String // true let str = 'xxx' str instanceof String // false
關(guān)于instanceof的實(shí)現(xiàn)原理,可以參考下面:
function myInstanceof(left, right) { // 這里先用typeof來判斷基礎(chǔ)數(shù)據(jù)類型,如果是,直接返回false if(typeof left !== 'object' || left === null) return false; // getProtypeOf是Object對象自帶的API,能夠拿到參數(shù)的原型對象 let proto = Object.getPrototypeOf(left); while(true) { if(proto === null) return false; if(proto === right.prototype) return true;//找到相同原型對象,返回true proto = Object.getPrototypeof(proto); } }
也就是順著原型鏈去找,直到找到相同的原型對象,返回true,否則為false
三、區(qū)別
typeof與instanceof都是判斷數(shù)據(jù)類型的方法,區(qū)別如下:
- typeof會返回一個(gè)變量的基本類型,instanceof返回的是一個(gè)布爾值
- instanceof 可以準(zhǔn)確地判斷復(fù)雜引用數(shù)據(jù)類型,但是不能正確判斷基礎(chǔ)數(shù)據(jù)類型
- 而 typeof 也存在弊端,它雖然可以判斷基礎(chǔ)數(shù)據(jù)類型(null 除外),但是引用數(shù)據(jù)類型中,除了 function 類型以外,其他的也無法判斷
1.對于對象、數(shù)組、null 返回的值是 object 。比如typeof(window),typeof(document),typeof(null)返回的值都是object。
2.對于函數(shù)類型,返回的值是 function。比如:typeof(eval),typeof(Date)返回的值都是function。
可以看到,上述兩種方法都有弊端,并不能滿足所有場景的需求
如果需要通用檢測數(shù)據(jù)類型,可以采用Object.prototype.toString,調(diào)用該方法,統(tǒng)一返回格式“[object Xxx]” 的字符串
如下
Object.prototype.toString({}) // "[object Object]" Object.prototype.toString.call({}) // 同上結(jié)果,加上call也ok Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call('1') // "[object String]" Object.prototype.toString.call(true) // "[object Boolean]" Object.prototype.toString.call(function(){}) // "[object Function]" Object.prototype.toString.call(null) //"[object Null]" Object.prototype.toString.call(undefined) //"[object Undefined]" Object.prototype.toString.call(/123/g) //"[object RegExp]" Object.prototype.toString.call(new Date()) //"[object Date]" Object.prototype.toString.call([]) //"[object Array]" Object.prototype.toString.call(document) //"[object HTMLDocument]" Object.prototype.toString.call(window) //"[object Window]"
了解了toString的基本用法,下面就實(shí)現(xiàn)一個(gè)全局通用的數(shù)據(jù)類型判斷方法
function getType(obj){ let type = typeof obj; if (type !== "object") { // 先進(jìn)行typeof判斷,如果是基礎(chǔ)數(shù)據(jù)類型,直接返回 return type; } // 對于typeof返回結(jié)果是object的,再進(jìn)行如下的判斷,正則返回結(jié)果 return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); }
使用如下
getType([]) // "Array" typeof []是object,因此toString返回 getType('123') // "string" typeof 直接返回 getType(window) // "Window" toString返回 getType(null) // "Null"首字母大寫,typeof null是object,需toString來判斷 getType(undefined) // "undefined" typeof 直接返回 getType() // "undefined" typeof 直接返回 getType(function(){}) // "function" typeof能判斷,因此首字母小寫 getType(/123/g) //"RegExp" toString返回
到此這篇關(guān)于菜鳥也能搞懂js中typeof與instanceof區(qū)別的文章就介紹到這了,更多相關(guān)js中typeof與instanceof內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
html5+CSS 實(shí)現(xiàn)禁止IOS長按復(fù)制粘貼功能
因?yàn)樵谝苿佣薃PP需要實(shí)現(xiàn)長按執(zhí)行別的事件,但是在iOS系統(tǒng)有默認(rèn)的長按選擇復(fù)制粘貼。禁止在網(wǎng)上找了很多資料,下面小編給大家分享解決方案,一起看看吧2016-12-12使用iframe實(shí)現(xiàn)pdf文件預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹了如何使用iframe實(shí)現(xiàn)pdf文件預(yù)覽功能,以及iframe預(yù)覽報(bào)錯(cuò)問題和iframe未能加載PDF文檔,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09javascript實(shí)現(xiàn)圖片輪換動作方法
這篇文章主要介紹了javascript實(shí)現(xiàn)圖片輪換動作方法,文章通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08基于HTML+JavaScript實(shí)現(xiàn)中國象棋
這篇文章主要為大家詳細(xì)介紹了如何利用HTML+CSS+JS實(shí)現(xiàn)中國象棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08JavaScript中的Reflect對象詳解(ES6新特性)
這篇文章主要介紹了JavaScript中的Reflect對象(ES6新特性)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07JS中超越現(xiàn)實(shí)的匿名函數(shù)用法實(shí)例分析
這篇文章主要介紹了JS中超越現(xiàn)實(shí)的匿名函數(shù)用法,結(jié)合實(shí)例形式分析了javascript匿名函數(shù)定義、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-06-06