在找工作過程中,很多人都會被問到類似這樣的問題,相信很多人都會脫口而出用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 的實現原理
總結
- typeof在判斷基本資料型別時是沒問題的。
- 如果需要判斷一個物件的具體型別,可以使用instanceof。但是instanceof不夠靈活,也可能判斷不準確。
- 要想比較準確的判斷物件例項的型別時,可以採取 Object.prototype.toString.call和Object.prototype.toString.apply。
推薦部落格: