公交车上荫蒂添的好舒服的电影-公用玩物(np双xing总受)-公用小荡货芊芊-公与妇仑乱hd-攻把受做哭边走边肉楼梯play-古装一级淫片a免费播放口

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

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

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

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

1. typeof操作符

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

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

例如:

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被錯誤地認為是一個對象。而對于函數類型,則返回"function".

2. instanceof操作符

instanceof操作符用于判斷一個對象是否屬于某個構造函數的實例。它比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判斷的結果是一個布爾值,如果對象是指定構造函數的實例,則返回true,否則返回false。

同時,也正是因為instanceof操作符可以判斷多層原型鏈中的實例關系,那函數和數組不也可以看作是一個對象嗎,那用他們用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方法的實現原理了,怎么這兩個結果都能是true呢。

這時候我們不妨先來大膽猜測一波,我們都知道,arr數組的創建實際是通過new構造函數Array()得到的,那arr就是構造函數Array()的一個實例對象,所以當我們判斷arr instanceof Array時, 如果在instanceof方法實現原理內部,用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)進行比較,這時候會發現他們是不是就相等啦,結果返回true。
欸,對嘍!就是這樣思路!非常的棒!實例對象 instanceof 數據類型 就是先通過判斷實例對象.__proto和數據類型的prototype是否相等,相等直接返回true,不相等就通過原型鏈,再往上找,看實例對象.__proto.__proto和數據類型的prototype是否相等,要是還不相等就再往上,直到實例對象.__proto.__proto.__proto為null了,還是和數據類型的prototype不相等,則返回false。
那我們帶著這個思路是不是非常清晰的就知道了instanceof方法的實現原理啦!接下來,我們一起手寫代碼來實現一下叭!代碼如下:

//L 實例對象

//R 要判斷的數據類型

function instanceOF(L,R){

    while(L !== null){

        // 用實例對象的__proto__屬性和要判斷的數據類型的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方法非常簡單啦!好,那既然數組,函數用instanceof方法和object數據類型進行判斷都為true,所以這種方法好像也不是那么完美,并不能精準判斷對象的類型。那我們不妨看看下面另一種方法。

3. Object.prototype.toString方法

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

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]" 

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


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



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

主站蜘蛛池模板: 国产高级桑拿在线播放 | 91免费在线 | 国产专区日韩欧美 | 国产三级自拍视频 | 精品无码在线播放国产 | 国产经典视频sm调教 | 97色伦午夜国产亚洲精品 | 国产97久久精品一区二区 | 动漫久章草在线视频播放国产 | 2025无码专区人妻系列日韩 | 91成人免费在线视频 | 国产精品成人竹菊影视亚洲一级黄 | 高清无码在线网 | 国产剧情中文字幕一区二区 | 国产精品成人一区二区不卡 | 91一区免费高清在线 | 国产毛片毛多水多的特级毛片 | 精品2025露脸国产偷人在视频 | 国产av夜夜欢一区二区三区 | 成人精品无码av综合 | 国产美女精 | av毛片uhd| 波多野结衣在线一区二区 | 国产人妻精品一区二区三区不卡 | 国产a网站 | 国产极品美女高潮无套app | 国产无码高清视频不卡 | 国产在线观看免费观看 | 国产在线精品国偷产拍 | 91麻豆精品国产电影 | 国产精品麻花传媒二三区别 | 黄色av电影在线观看 | 国产成在线观看免费视频成本人 | 国产成人精品无码片网站 | 国产综合精品99久久久久 | 国产在线一二三精品观看 | 国产激情一区二区三区成人免费 | 国产精品无码av在线播放 | 精品无码91久久精品无码一区 | 精品亚洲一区二区在线播放 | 69国产成人综合久久精品91 |