狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

三種“類型判斷”的方法,一起手寫instanceof方法的實現(xiàn)原理

freeflydom
2023年11月27日 11:58 本文熱度 623

在Javascript中,有三種常用的方法用于判斷數(shù)據(jù)類型:

1. typeof操作符

typeof操作符是最常用的判斷數(shù)據(jù)類型的方法之一。它是一個一元操作符,可以用于判斷一個值的數(shù)據(jù)類型,并返回一個表示該數(shù)據(jù)類型的字符串。常見的typeof返回值有:

- "undefined": 用于表示未定義的變量
- "number": 用于表示數(shù)字類型
- "string": 用于表示字符串類型
- "boolean": 用于表示布爾類型
- "object": 用于表示對象類型(包括數(shù)組、日期、正則表達式等)
- "function": 用于表示函數(shù)類型
- "bigint": 用于表示大數(shù)字類型
- "symbol": 用于保證創(chuàng)建的值不與其他屬性名產(chǎn)生沖突

例如:

typeof undefined; // "undefined"  

typeof 42; // "number"  

typeof "hello"; // "string"  

typeof true; // "boolean"  

typeof { name: "John" }; // "object"  

typeof function() {}; // "function"  

typeof 123n; // "bigint"

typeof symbol('hello'); //"symbol"

需要注意的是,typeof對于null的判斷返回的是"object",這是因為在Javascript的早期版本中,null被錯誤地認為是一個對象。而對于函數(shù)類型,則返回"function".

2. instanceof操作符

instanceof操作符用于判斷一個對象是否屬于某個構造函數(shù)的實例。它比typeof更適用于判斷對象類型,因為它可以準確地判斷多層原型鏈中的實例關系。例如:

var arr = [];  

var date = new Date();  

var obj = {};

var fn = function(){};

  

arr instanceof Array; // true  

date instanceof Date; // true  

obj instanceof Object; // true  

fn instanceof Function; // true  

instanceof判斷的結果是一個布爾值,如果對象是指定構造函數(shù)的實例,則返回true,否則返回false。

同時,也正是因為instanceof操作符可以判斷多層原型鏈中的實例關系,那函數(shù)和數(shù)組不也可以看作是一個對象嗎,那用他們用instanceof操作符來判斷和Object的關系,是不是也能得到true呢,我們來看一看:

var arr = []; 

var fn = function(){};


arr instanceof Object; // true  

fn instanceof Object; // true  

結果也是true,欸,arr instanceof Array是true,arr instanceof Object也是true,這時候我們是不是開始好奇instanceof方法的實現(xiàn)原理了,怎么這兩個結果都能是true呢。

這時候我們不妨先來大膽猜測一波,我們都知道,arr數(shù)組的創(chuàng)建實際是通過new構造函數(shù)Array()得到的,那arr就是構造函數(shù)Array()的一個實例對象,所以當我們判斷arr instanceof Array時, 如果在instanceof方法實現(xiàn)原理內(nèi)部,用arr的隱式原型(arr.__proto__)去和Array的顯示原型(Array.prototype)比較,相等就返回true,否則返回false,通過原型的知識,這么想arr instanceof Array返回true是不是非常合情合理。(注:如果還有不太懂原型知識的小伙伴可以先看看我之前的原型知識文章喔~
但是,又好像還差一點吼,那用剛剛那個想法判斷arr instanceof Object,這時候就要用arr的隱式原型(arr.__proto__)去和Object的顯示原型(Object.prototype)進行比較了,那他兩是不是很明顯就不相等了,這時估計有看過我原型文章聰明的小伙伴知道了,這時候他們不相等,arr的隱式原型arr.__proto__對象會再用它的隱式原型,也就是arr.__proto__.__proto__,再去和Object的顯示原型(Object.prototype)進行比較,這時候會發(fā)現(xiàn)他們是不是就相等啦,結果返回true。
欸,對嘍!就是這樣思路!非常的棒!實例對象 instanceof 數(shù)據(jù)類型 就是先通過判斷實例對象.__proto和數(shù)據(jù)類型的prototype是否相等,相等直接返回true,不相等就通過原型鏈,再往上找,看實例對象.__proto.__proto和數(shù)據(jù)類型的prototype是否相等,要是還不相等就再往上,直到實例對象.__proto.__proto.__proto為null了,還是和數(shù)據(jù)類型的prototype不相等,則返回false。
那我們帶著這個思路是不是非常清晰的就知道了instanceof方法的實現(xiàn)原理啦!接下來,我們一起手寫代碼來實現(xiàn)一下叭!代碼如下:

//L 實例對象

//R 要判斷的數(shù)據(jù)類型

function instanceOF(L,R){

    while(L !== null){

        // 用實例對象的__proto__屬性和要判斷的數(shù)據(jù)類型的prototype進行判斷

        //相等返回true,不相等再用實例對象的__proto__的__proto__屬性去判斷

        //直到L.__proto__.__proto__...為null,就通過原型鏈根本找不到相等的了,返回false.

        if(L.__proto__ === R.prototype){  

            return true

        }

        else L = L.__proto__

    }

    return false

}


//驗證我們手寫的instanceOF是否正確

console.log(instanceOF([],Array)); //true

console.log(instanceOF([],Object));//true

所以,搞明白之后,是不是覺得手寫instanceof方法非常簡單啦!好,那既然數(shù)組,函數(shù)用instanceof方法和object數(shù)據(jù)類型進行判斷都為true,所以這種方法好像也不是那么完美,并不能精準判斷對象的類型。那我們不妨看看下面另一種方法。

3. Object.prototype.toString方法

Object.prototype.toString是一個通用的方法,可以返回一個對象的內(nèi)部屬性[[Class]]的值,從而判斷對象的類型。toString方法被重寫,并通過不同的內(nèi)部屬性來標識不同的類型。例如:

Object.prototype.toString.call(undefined); // "[object Undefined]"  

Object.prototype.toString.call(42); // "[object Number]"  

Object.prototype.toString.call("hello"); // "[object String]"  

Object.prototype.toString.call(true); // "[object Boolean]"  

Object.prototype.toString.call({ name: "John" }); // "[object Object]"  

Object.prototype.toString.call(function() {}); // "[object Function]"  

這時小伙伴要問啦,不是講Object.prototype.toString方法嘛,怎么后面還跟了一個call方法呢,好,這時候我們試試不加call方法,看看結果如何:

console.log(Object.prototype.toString(undefined))// "[object Object]"

console.log(Object.prototype.toString(42))// "[object Object]"  

console.log(Object.prototype.toString("hello"))// "[object Object]" 

這時會發(fā)現(xiàn)結果都是[object Object]對象類型,當直接調(diào)Object.prototype.toString時,它的 this 值會被設置為 toString 方法的調(diào)用者,也就是要檢查類型的對象本身,這里就是Object.prototype對象,所以得到的結果都是對象類型。這時可以通過call方法來改變它的調(diào)用者,從而將this值設置為我們想要檢查類型的對象。這樣做可以確保我們獲取到了準確的內(nèi)部屬性 [[Class]] 的信息,用于判斷對象的類型。所以,使用Object.prototype.toString.call方法可以準確地檢查對象的類型,而不受調(diào)用者的影響。這是一種常用的方法來判斷對象類型的標準做法。


作者:小米露
鏈接:https://juejin.cn/post/7299742103688265769
來源:稀土掘金
著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。



該文章在 2023/11/27 11:58:52 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved