欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS類型判斷的四種方法詳解

 更新時間:2024年08月19日 08:25:59   作者:今天一定晴q  
JavaScript中有七種原始數(shù)據(jù)類型和幾種引用數(shù)據(jù)類型,本文將清楚地介紹四種用于類型判斷的方法,分別是typeOf、instanceOf、Object.prototype.toString.call()、Array.isArray(),并介紹其使用方法和判定原理,需要的朋友可以參考下

引言

JavaScript中有七種原始數(shù)據(jù)類型和幾種引用數(shù)據(jù)類型,本文將清楚地介紹四種用于類型判斷的方法,分別是typeOf、instanceOfObject.prototype.toString.call()、Array.isArray(),并介紹其使用方法和判定原理。

typeof

  • 可以準確判斷除null之外的所有原始類型,null會被判定成object
  • function類型可以被準確判斷為function,而其他所有引用類型都會被判定為object
let s = '123'   // string
let n = 123    // number
let f = true   // boolean
let u = undefined   // undefined
let nu = null    // null
let sy = Symbol(123)   // Symbol
let big = 1234n    // BigInt

let obj = {}
let arr = []
let fn = function() {}
let date = new Date()

console.log(typeof s);  // string    typeof后面有無括號都行
console.log(typeof n);  // number   
console.log(typeof f);  // boolean
console.log(typeof u);  // undefined
console.log(typeof(sy));  // symbol
console.log(typeof(big));  // bigint

console.log(typeof(nu));  // object

console.log(typeof(obj));  // object
console.log(typeof(arr));  // object
console.log(typeof(date));  // object

console.log(typeof(fn));  // function

判定原理

typeof是通過將值轉(zhuǎn)換為二進制之后,判斷其前三位是否為0:都是0則為object,反之則為原始類型。因為原始類型轉(zhuǎn)二進制,前三位一定不都是0;反之引用類型被轉(zhuǎn)換成二進制前三位一定都是0。

null是原始類型卻被判定為object就是因為它在機器中是用一長串0來表示的,可以把這看作是一個史詩級的bug。

所以用typeof判斷接收到的值是否為一個對象時,還要注意排除null的情況:

function isObject() {
    if(typeof(o) === 'object' && o !== null){
        return  true
    }
    return false
}

你丟一個值給typeof,它會告訴你這個字值是什么類型,但是它無法準確告訴你這是一個Array或是Date,若想要如此精確地知道一個對象類型,可以用instanceof告訴你是否為某種特定的類型

instanceof

只能精確地判斷引用類型,不能判斷原始類型

console.log(obj instanceof Object);// true
console.log(arr instanceof Array);// true
console.log(fn instanceof Function);// true
console.log(date instanceof Date);// true
console.log(s instanceof String);// false
console.log(n instanceof Number);// false
console.log(arr instanceof Object);// true  

判定原理

instanceof既能把數(shù)組判定成Array,又能把數(shù)組判定成Object,究其原因是原型鏈的作用————順著數(shù)組實例 arr 的隱式原型一直找到了 Object 的構(gòu)造函數(shù),看下面的代碼:

arr.__proto__ = Array.prototype
Array.prototype.__proto__ = Object.prototype

所以我們就知道了,instanceof能準確判斷出一個對象是否為某種類型,就是依靠對象的原型鏈來查找的,一層又一層地判斷直到找到null為止。

手寫instanceOf

根據(jù)這個原理,我們可以手寫出一個instanceof:

function myinstanceof(L, R) {
    while(L != null) {
        if(L.__proto__ === R.prototype){
            return true;
        }
        L = L.__proto__;
    }
    return false;
}

console.log(myinstanceof([], Array))  // true
console.log(myinstanceof({}, Object))  // true

Object.prototype.toString.call()

可以判斷任何數(shù)據(jù)類型

在瀏覽器上執(zhí)行這三段代碼,會得到'[object Object]','[object Array]''[object Number]'

var a = {}
Object.prototype.toString.call(a)

var a = {}
Object.prototype.toString.call(a)

var a = 123
Object.prototype.toString.call(a)

原型上的toString的內(nèi)部邏輯

調(diào)用Object.prototype.toString的時候執(zhí)行會以下步驟:

  • 如果此值是undefined類型,則返回 ‘[object Undefined]’
  • 如果此值是null類型,則返回 ‘[object Null]’
  • 將 O 作為 ToObject(this) 的執(zhí)行結(jié)果。toString執(zhí)行過程中會調(diào)用一個ToObject方法,執(zhí)行一個類似包裝類的過程,我們訪問不了這個方法,是JS自己用的
  • 定義一個class作為內(nèi)部屬性[[class]]的值。toString可以讀取到這個值并把這個值暴露出來讓我們看得見
  • 返回由 "[object"class"]" 組成的字符串

為什么結(jié)合call就能準確判斷值類型了呢?

Object.prototype.toString(xxx)往括號中不管傳遞什么返回結(jié)果都是'[object Object]',因為根據(jù)上面五個步驟來看,它內(nèi)部會自動執(zhí)行ToObject()方法,xxx會被執(zhí)行一個類似包裝類的過程然后轉(zhuǎn)變成一個對象。所以單獨一個Object.prototype.toString(xxx)不能用來判定值的類型

② 首先了解call方法的核心原理就是:比如foo.call(obj),利用隱式綁定的規(guī)則,讓obj對象擁有foo這個函數(shù)的引用,從而讓foo函數(shù)的this指向obj,執(zhí)行完foo函數(shù)內(nèi)部邏輯后,再將foo函數(shù)的引用從obj上刪除掉。手搓一個call的源碼就是這樣的:

// call方法只允許被函數(shù)調(diào)用,所以它應(yīng)該是放在Function構(gòu)造函數(shù)的顯式原型上的
Function.prototype.mycall = function(context) {
    // 判斷調(diào)用我的那個哥們是不是函數(shù)體
    if (typeof this !== 'function') {
      return new TypeError(this+ 'is not a function')
    }
  
    // this(函數(shù))里面的this => context對象
    const fn = Symbol('key')  // 定義一個獨一無二的fn,防止使用該源碼時與其他fn產(chǎn)生沖突
    context[fn] = this  // 讓對象擁有該函數(shù)  context={Symbol('key'): foo}
    context[fn]()  // 觸發(fā)隱式綁定
    delete context[fn]
  }

③ 所以Object.prototype.toString.call(xxx)就相當于 xxx.toString(),把toString()方法放在了xxx對象上調(diào)用,這樣就能精準給出xxx的對象類型

toString方法有幾個版本:

{}.toString() 得到由"[object" 和 class 和 "]" 組成的字符串

[].toString() 數(shù)組的toString方法重寫了對象上的toString方法,返回由數(shù)組內(nèi)部元素以逗號拼接的字符串

xx.toString() 返回字符串字面量,比如

let fn = function(){}; 
console.log( fn.toString() ) //  "function () {}"

Array.isArray(x)

只能判斷是否是數(shù)組,若傳進去的x是數(shù)組,返回true,否則返回false

總結(jié)

typeOf:原始類型除了null都能準確判斷,引用類型除了function能準確判斷其他都不能。依靠值轉(zhuǎn)為二進制后前三位是否為0來判斷

instanceOf:只能把引用類型丟給它準確判斷。順著對象的隱式原型鏈向上比對,與構(gòu)造函數(shù)的顯式原型相等返回true,否則false

Object.prototype.toString.call():可以準確判斷任何類型。要了解對象原型的toString()內(nèi)部邏輯和call()的核心原理,二者結(jié)合才有精準判定的效果

Array.isArray():是數(shù)組則返回true,不是則返回false。判定范圍最狹窄

以上就是JS類型判斷的四種方法詳解的詳細內(nèi)容,更多關(guān)于JS類型判斷的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript子窗口調(diào)用父窗口變量和函數(shù)的方法

    JavaScript子窗口調(diào)用父窗口變量和函數(shù)的方法

    這篇文章主要介紹了JavaScript子窗口調(diào)用父窗口變量和函數(shù)的方法,涉及JavaScript窗口調(diào)用的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Javascript this 的一些學(xué)習(xí)總結(jié)

    Javascript this 的一些學(xué)習(xí)總結(jié)

    相信有C++、C#或Java等編程經(jīng)驗的各位,對于this關(guān)鍵字再熟悉不過了。由于Javascript是一種面向?qū)ο蟮木幊陶Z言,它和C++、C#或Java一樣都包含this關(guān)鍵字,接下來我們將向大家介紹Javascript中的this關(guān)鍵字
    2012-08-08
  • JS常用算法實現(xiàn)代碼

    JS常用算法實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了用JS常用幾個算法的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 原生js的ajax和解決跨域的jsonp(實例講解)

    原生js的ajax和解決跨域的jsonp(實例講解)

    下面小編就為大家?guī)硪黄鷍s的ajax和解決跨域的jsonp(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • javascript觸發(fā)模擬鼠標點擊事件

    javascript觸發(fā)模擬鼠標點擊事件

    這篇文章主要介紹了javascript觸發(fā)模擬鼠標點擊事件,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-06-06
  • 輸入密碼時檢測大寫是否鎖定的js代碼

    輸入密碼時檢測大寫是否鎖定的js代碼

    網(wǎng)站登錄為了更好的用戶體驗都會在輸入密碼的時候檢測是否開啟大寫。提醒用戶。
    2011-02-02
  • JS制作可以選項卡切換的年歷

    JS制作可以選項卡切換的年歷

    這篇文章主要為大家分享了JS制作類似于選項卡切換的年歷,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 深入理解requireJS-實現(xiàn)一個簡單的模塊加載器

    深入理解requireJS-實現(xiàn)一個簡單的模塊加載器

    本篇文章主要介紹了深入理解requireJS-實現(xiàn)一個簡單的模塊加載器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • js滾動條多種樣式,推薦

    js滾動條多種樣式,推薦

    [紅色]js滾動條多種樣式,推薦...
    2007-02-02
  • 舉例說明javascript冒泡排序

    舉例說明javascript冒泡排序

    這篇文章主要為大家介紹了javascript冒泡排序,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11

最新評論