javascript中如何判斷變數的型別?

veriazzzz發表於2019-03-27

在找工作過程中,很多人都會被問到類似這樣的問題,相信很多人都會脫口而出用typeof。下面我們來分析下,如何準確回答此類問題。

1、typeof

typeof一般被用來判斷一個變數的型別,我們可以利用它判斷number,string, object,bolean,function,undefined,symbol這7中型別,也就是javascript中的資料型別。這種判斷能幫我們搞定一些問題,例如在判斷一些非object型別變數時,它能告訴我們是哪一種型別。但判斷Object型別的變數時,只能告訴我們是Object型別,而不能具體到哪一種Object。

let s = new Number(4);
typeof s === 'object'; // true
instanceof s ===  Number // true
複製程式碼

當然typeof除了判斷Object型別不準確外,還有一種情況下會出現異常:Null,由於Null的在js底層儲存變數的機器碼均為0,而物件Object在底層儲存變數的機器碼也均為0,因此,typeof在判斷變數型別時把Null被當做物件來看。綜上所述,我們在利用typeof來判斷變數型別時,應該避免對Null的判斷。

2、Object.prototype.toString

var a = [1, 2, 3, 4, 5];
var b = function () { }
var c = { 'age': 18, 'sex': '男' }
console.log(typeof a, typeof b, typeof c); // object function object
console.log(Object.prototype.toString.apply(a), Object.prototype.toString.call(a), Object.prototype.toString.apply(a)); //  [object Array] [object Array] [object Array]
console.log(Object.prototype.toString.apply(b), Object.prototype.toString.call(b), Object.prototype.toString.apply(b)); // [object Function] [object Function] [object Function]
console.log(Object.prototype.toString.apply(c), Object.prototype.toString.call(c), Object.prototype.toString.apply(c)); // [object Object] [object Object] [object Object]
複製程式碼

3、instanceof

前面我們提到利用instanceof來判斷物件的具體型別。與 typeof 方法不同的是,instanceof 方法要求開發者明確地確認物件為某特定型別。如:

var oStringObject = new String("hello world"); 
console.log(oStringObject instanceof String);   // 輸出 "true"
複製程式碼

儘管不像typeof靈活,但在判斷Object物件具體型別的情況下,instanceof派上用場。他用於檢測左邊物件是不是右邊物件的例項。 其實instanceof的實現原理就是隻要右邊變數的prototype在左邊變數的原型鏈上即可。如果在,則返回true;否則返回false。特別說明一點,要避免使用instance檢測Null變數,因為會報異常,這是javasctipt底層的bug。

function new_instance_of(leftVaule, rightVaule) { 
    let rightProto = rightVaule.prototype; // 取右表示式的 prototype 值
    leftVaule = leftVaule.__proto__; // 取左表示式的__proto__值
    while (true) {
    	if (leftVaule === null) {
            return false;	
        }
        if (leftVaule === rightProto) {
            return true;	
        } 
        leftVaule = leftVaule.__proto__ 
    }
}
複製程式碼

注:此程式碼轉載自 淺談 instanceof 和 typeof 的實現原理

總結

  1. typeof在判斷基本資料型別時是沒問題的。
  2. 如果需要判斷一個物件的具體型別,可以使用instanceof。但是instanceof不夠靈活,也可能判斷不準確。
  3. 要想比較準確的判斷物件例項的型別時,可以採取 Object.prototype.toString.call和Object.prototype.toString.apply。

推薦部落格:

  1. 淺談 instanceof 和 typeof 的實現原理
  2. javascript中原型鏈與instanceof原理
  3. JavaScript instanceof 運算子深入剖析
  4. 前端面試instanceof原理

相關文章