最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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、instanceOf、Object.prototype.toString.call()Array.isArray(),并介紹其使用方法和判定原理。

typeof

  • 可以準(zhǔn)確判斷除null之外的所有原始類型,null會被判定成object
  • function類型可以被準(zhǔn)確判斷為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,它會告訴你這個字值是什么類型,但是它無法準(zhǔn)確告訴你這是一個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能準(zhǔn)確判斷出一個對象是否為某種類型,就是依靠對象的原型鏈來查找的,一層又一層地判斷直到找到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就能準(zhǔn)確判斷值類型了呢?

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)就相當(dāng)于 xxx.toString(),把toString()方法放在了xxx對象上調(diào)用,這樣就能精準(zhǔn)給出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都能準(zhǔn)確判斷,引用類型除了function能準(zhǔn)確判斷其他都不能。依靠值轉(zhuǎn)為二進制后前三位是否為0來判斷

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

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

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

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

相關(guān)文章

  • JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實例

    JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實例

    這篇文章主要介紹了JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實例,本文先是講解了聲明數(shù)組的方法,然后對4個函數(shù)使用給出了一些例子,需要的朋友可以參考下
    2014-08-08
  • 兩個Javascript小tip資料

    兩個Javascript小tip資料

    兩個Javascript小tip資料,學(xué)習(xí)js的朋友可以參考下。
    2010-11-11
  • 解決Jstree 選中父節(jié)點時被禁用的子節(jié)點也會選中的問題

    解決Jstree 選中父節(jié)點時被禁用的子節(jié)點也會選中的問題

    下面小編就為大家分享一篇解決Jstree 選中父節(jié)點時被禁用的子節(jié)點也會選中的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • js 通過cookie實現(xiàn)刷新不變化樹形菜單

    js 通過cookie實現(xiàn)刷新不變化樹形菜單

    通過設(shè)置cookie來保存樹形菜單的狀態(tài),在頁面加載時重新讀取cookie來設(shè)置菜單
    2014-10-10
  • JS訪問對象兩種方式區(qū)別解析

    JS訪問對象兩種方式區(qū)別解析

    這篇文章主要介紹了JS訪問對象兩種方式區(qū)別解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • 用js的for循環(huán)獲取radio選中的值

    用js的for循環(huán)獲取radio選中的值

    獲取radio選中值的方法有很多,在本文為大家介紹的是使用for循環(huán)來實現(xiàn),具體的實現(xiàn)如下,感興趣的朋友可以參考下
    2013-10-10
  • JavaScript性能調(diào)優(yōu)實戰(zhàn)案例(附完整代碼)

    JavaScript性能調(diào)優(yōu)實戰(zhàn)案例(附完整代碼)

    JavaScript性能優(yōu)化是一個持續(xù)的過程,需要結(jié)合具體場景靈活運用各種策略,下面這篇文章主要介紹了JavaScript性能調(diào)優(yōu)實戰(zhàn)的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2026-04-04
  • JavaScript可迭代對象詳細介紹

    JavaScript可迭代對象詳細介紹

    ES6中引入了迭代器與可迭代對象的概念,并且提供了對可迭代對象的相關(guān)支持,如for...of循環(huán),Map(iterable)構(gòu)造器,展開語法...等。讓我們對數(shù)組外的數(shù)據(jù)集合的遍歷操作也得到極大簡化
    2022-06-06
  • ionic 自定義彈框效果

    ionic 自定義彈框效果

    這篇文章主要介紹了ionic 自定義彈框效果,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-06-06
  • 微信小程序中weui用法解析

    微信小程序中weui用法解析

    這篇文章主要介紹了微信小程序中weui用法解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10

最新評論

上高县| 庐江县| 贵德县| 绥滨县| 修武县| 南阳市| 祁东县| 老河口市| 阿坝县| 宽城| 林周县| 蕉岭县| 台北市| 山丹县| 汕尾市| 黑河市| 武川县| 临潭县| 虞城县| 炉霍县| 大厂| 呼和浩特市| 揭东县| 沙河市| 曲阜市| 曲阳县| 白玉县| 西宁市| 克什克腾旗| 新绛县| 诏安县| 新郑市| 新龙县| 宣恩县| 龙南县| 尼玛县| 白河县| 兴城市| 东港市| 航空| 杭锦旗|