JS類型判斷---typeof, constructor, instanceof, toString

JS中的數據類型

js中,根據存儲的方式不一樣(參見文末鏈接), 數據能夠劃分爲如下兩大類型:數組

  • 原始類型

    string, number, boolean, undefined, null, symbol函數

  • 引用類型

    Object (Array, Function, RegExp, Date)post

數據類型判斷

判斷數據的所屬類型此處列舉四種方法,並對每種方法使用的範圍以及限制進行說明.若是對原型鏈還不熟悉的同窗,請先閱讀相關的原型鏈知識(見文末)ui

  1. typeof

    typeof 通常僅用於判斷原始類型(不包含null),返回值爲該類型的字符串this

    console.log(typeof 'str');  // string
    console.log(typeof 1);      // number
    console.log(typeof true); // boolean
    console.log(typeof undefined); // undefined
    console.log(typeof Symbol()); // symbol
    複製代碼

    注意: typeof不能用於判斷原始類型中的null以及引用類型object,結果都會返回字符串object(Function類型除外,結果會返回function,但在在 IE 6, 7 和 8 上則返回object)spa

    console.log(typeof null);  // object
    console.log(typeof {}); // object
    console.log(typeof alert); // function
    console.log(typeof []); // object
    console.log(typeof new RegExp()); // object
    console.log(typeof new Date()); // object
    複製代碼
  2. contructor

    constructor主要是利用原型上的prototype.constructor指向實例的構造函數來進行判斷的prototype

    先定義一個構造函數Animal, 並new一個實例dog3d

    const Animal = function (name) {this.name = name};   // 聲明一個構造函數
    let dog = new Animal('dog'); // 生成實例dog
    複製代碼

    聲明Animal函數的同時js會在Animal上掛載一個prototype對象,同時在prototype對象上會自動生成一個constructor屬性並指向構造函數Animal,至關於:
    Animal.prototype.constructor === Animal // true ,根據原型鏈的查找原則, console(dog.prototype) // Animal 因此利用構造函數原型上的constructor屬性能夠判斷當前實例是否爲當前構造函數的實例,進而肯定數據所屬類型:code

    console.log('1'.constructor === String);  // true
    console.log(new Number(1).constructor === Number); // true
    console.log(true.constructor === Boolean); // true
    console.log(alert.constructor === Function); // true
    console.log([].constructor === Array); // true
    console.log(new Date().constructor === Date); // true
    複製代碼

    注意:對象

    1. null, undefined 是無效的對象,所以是不會有 constructor 存在的,這兩種類型的數據須要經過其餘方式來判斷。
    2. 函數的 constructor 是不穩定的,這個主要體如今自定義對象上,當開發者重寫 prototype 後,原有的 constructor 引用會丟失,constructor 會默認爲 Object

    constructor 判斷類型的限制過多且不許確,容易出錯,少用,或者不用!

  3. instanceof

    typeofconstructor 不一樣, instanceof通常用於判斷引用類型,返回值爲布爾值, 例如:

    [] instanceof Array // true

    instanceof 是經過判斷當前實例的原型與構造函數的原型是否爲同一對象,進而肯定當前數據的類型,這樣講或許不夠明瞭,咱們簡單實現一下 instanceof

    const self_instanceof = function (instance, constructor) {
        let instance_proto = instance.__proto__;
        let constructor_proto = constructor.prototype;
    
        while(true) {
            // 找到終點返回false
           if (instance_proto === null) {return false};
           // 找到返回true
           if (instance_proto === constructor_proto) {return true};
            // 當實例與構造函數原型不相同, 沿着原型鏈繼續向上查找
            instance_proto = instance_proto.__proto__;
        }
    }
    console.log([] instanceof Array)   // true
    console.log(self_instanceof([], Array))  // true
    複製代碼

    當一個頁面存在多個iframe時,也就是存在多個全局變量window,instanceof的判斷會被來自不一樣的iframe的數據所幹擾,致使不可信

    假設:頁面pageA 經過iframe內嵌了頁面pageB, 此時pageB傳遞了一個數組 let arrB = []到頁面 pageA, 若在pageA使用instanceof判斷數組arrB會出現 arrB instanceof Array // false 主要緣由是由於 arrB 是由pageB上的Array構造出來的

    要避免這種問題可使用Es6提供的數組靜態方法 Array.isArray, 或者咱們即將提到的toString方法進行判斷
    Array.isArray(arrB) // true

  4. toString

    toStringObject.prototype上的一個方法, 經常使用方式爲 Object.prototype.toString.call(target)
    返回值是 [object 類型]字符串,該方法基本上能判斷全部的數據類型(自定義數據類型除外)

    // 定義判斷類型函數
    let getType = target => Object.prototype.toString.call(target)
    
    console.log(getType('')); // [object String]
    console.log(getType(2)); // [object Number]
    console.log(getType(true)); // [object Boolean]
    console.log(getType(undefined)); // [object Undefined]
    console.log(getType(null)); // [object Null]
    console.log(getType(Symbol())); // [object Symbol]
    console.log(getType({})); // [object Object]
    console.log(getType([])); // [object Array]
    console.log(getType(alert)); // [object Function]
    console.log(getType(new RegExp())); // [object RegExp]
    console.log(getType(new Date())); // [object Date]
    複製代碼

    該方法準確穩定,推薦使用

以上爲類型判斷的一些看法, 有不當之處, 還請大佬們指正!

相關知識點文章請參考:

詳細圖解 JavaScript 內存空間
JS原型鏈與繼承別再被問倒了

相關文章
相關標籤/搜索