js--typeof 和 instanceof 判斷資料型別的區別及開發中的使用

丶Serendipity丶發表於2021-10-17

前言

  日常的開發中,我們經常會遇到判斷一個變數的資料型別或者該變數是否為空值的情況,你是如何去選擇判斷型別的操作符的?本文來總結記錄一下我們開發人員必須掌握的關於 typeof 和 instanceof 的知識點以及在開發中的使用建議,同時在面試過程中也經常會遇到這樣的問題。

正文

  1、typeof 操作符

  typeof 操作符,確定任意變數的資料型別,確切說,它是判斷一個變數是否為字串、數值、布林值或 undefined 的最好方式。其返回值為字串型別,其使用方法如下:typeof 是一個操作符,不是一個函式,但是使用可以將變數作為引數傳入:
  a、typeof  operand
  b、typeof (operand)
  (1)返回值為字串型別,其中:
  

返回值

含義值

"undefined"

未定義

"boolean"

布林值

"string"

字串

"number"

數值

 "object"

物件(而不是函式)或 null

"function"

函式

"symbol"

符號

  (2)常見使用方法

        console.log(typeof undefined);//'undefined'
        console.log(typeof true);//'bpplean'
        console.log(typeof ("number"));  //'string'
        console.log(typeof "number");  //'string' 
        console.log(typeof 1);//'number'
        console.log(typeof Symbol());//'symbol'
        //對於Array,Null等特殊物件使用typeof一律返回object,這正是typeof的侷限性
        console.log(typeof null);   //'object'
        console.log(typeof [1, 2, 3]);//'object'
        console.log(typeof undefined);  //'undefined'
        //通過 typeof 操作符來區分函式和其他物件
        function f1() { console.log(111); }
        console.log(typeof f1);  //'function'  
        console.log(typeof f1());  // 111 'undefined'
  
  (3)不能通過typeof 來判斷一個變數是否存在
        var a;
        if (a === undefined) {
            console.log("變數不存在")
        } else {
            console.log("變數存在")
        }
     // 變數不存在

  2、instanceof 操作符

  typeof雖然對原始值很有用,但它對引用值的用處不大。我們通常不關心一個值是不是物件,而是想知道它是什麼型別的物件。為了解決這個問題,ECMAScript 提供了 instanceof 操作符。使用如下:

        function f1() { console.log(111); }
        console.log(f1 instanceof Object);//true
        console.log(f1 instanceof Function);//true
        console.log(f1 instanceof RegExp);//false

  所有引用值都是 Object 的例項,因此通過 instanceof 操作符檢測任何引用值和Object 建構函式都會返回 true 。類似地,如果用 instanceof 檢測原始值,則始終會返回 false ,因為原始值不是物件。

  instanceof 運算子用於判斷建構函式的 prototype 屬性是否出現在物件的原型鏈中的任何位置。其實現原理如下:

  function myInstanceof(left, right) {
    let proto = Object.getPrototypeOf(left), // 獲取物件的原型
    prototype = right.prototype; // 獲取建構函式的 prototype 物件

  // 判斷建構函式的 prototype 物件是否在物件的原型鏈上
    while (true) {
      if (!proto) return false;
      if (proto === prototype) return true;
      proto = Object.getPrototypeOf(proto);
    }
 }

  3、typeof 和 instanceof 的區別以及開發中的使用建議

  typeof 與 instance 都是判斷資料型別的方法,區別如下:

  • typeof會返回一個變數的基本型別,instanceof返回的是一個布林值

  • instanceof 可以準確地判斷複雜引用資料型別,但是不能正確判斷基礎資料型別

  • typeof 也存在弊端,它雖然可以判斷基礎資料型別(null 除外),但是引用資料型別中,除了 function 型別以外,其他的也無法判斷

  可以看到,上述兩種方法都有弊端,並不能滿足所有場景的需求

  如果需要通用檢測資料型別,建議採用Object.prototype.toString,呼叫該方法,統一返回格式“[object Xxx]” 的字串。使用如下:

        console.log(Object.prototype.toString.call(undefined))  //"[object Undefined]"
        console.log(Object.prototype.toString.call(true))  // "[object Boolean]"
        console.log(Object.prototype.toString.call('1'))  // "[object String]"
        console.log(Object.prototype.toString.call(1))    // "[object Number]"
        console.log(Object.prototype.toString.call(Symbol()))    // "[object Symbol]"
        console.log(Object.prototype.toString.call({}))   // "[object Object]"
        console.log(Object.prototype.toString.call(function () { }))   // "[object Function]"
        console.log(Object.prototype.toString.call([]))       //"[object Array]"
        console.log(Object.prototype.toString.call(null))    //"[object Null]"
        console.log(Object.prototype.toString.call(/123/g))     //"[object RegExp]"
        console.log(Object.prototype.toString.call(new Date()))  //"[object Date]"

 

寫在最後

  以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。

 

相關文章