JavaScript使用原型判斷物件型別
1. constructor屬性
在JavaScript建立物件(二)——建構函式模式中,我們說過可以使用物件的constructor
屬性判斷物件的型別:p1.constructor === Person
,可能當時就有細心的讀者會想,我們並沒有給這個物件新增過constructor
,這個屬性是從哪兒來的呢?講過原型之後,我們知道這個屬性是原型中的,所以一般重寫原型時也都會把constructor
補上。
我們可以通過像下面的程式碼一樣,切斷例項與原型的關係:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor: Person,
sayName: function(){
console.log(this.name);
}
}
var p1 = new Person('張三', 18, 'JavaScript');
var p2 = new Person('李四', 20, 'Java');
//切斷p1與Person原型的關係
p1.__proto__ = null;
console.log(p1.constructor === Person) ;//false
console.log(p2.constructor === Person);//true
如程式碼所示,切斷p1
與Person
原型的關係後,p1.constructor === Person
的結果為false
,constructor
屬性失效了。
工廠模式沒辦法使用這種方法判讀物件的型別,為什麼呢?因為使用工廠模式建立的物件本質上只是一個Object
型別,它們的constructor
屬性都是Object
,所以沒辦法通過constructor
區分物件的型別。
2. instanceof關鍵字
之前我們還使用過instanceof
判斷物件的型別,該方法不僅可以判斷物件本身的型別,還能判斷出父型別,其實這個關鍵字也是依賴原型的。還是以上述p1
console.log(p1 instanceof Person);//false
console.log(p1 instanceof Object);//false
如程式碼所示,p1
的原型被置為null
後,instanceof
也失效了。
3. isPrototypeOf()方法
這是原型物件上的一個方法,用於判斷物件的原型。那麼問題又來了,我們明明重寫了Person
的原型,並且也沒有宣告isPrototypeOf()
方法,這個方法是從哪來的呢?這就涉及到原型鏈的知識了,以後再講。仍然以上述p1
、p2
為例,看下面程式碼:
console.log(Person.prototype.isPrototypeOf(p1));//false
console.log(Person.prototype.isPrototypeOf(p2));//true
如程式碼所示,p1
切斷了與原型的關係,結果為false
。p2
的原型就是Person.prototype
,結果為true。
4. getprototypeof()方法
這是Object
上的一個方法,可以直接獲取到例項的原型物件,看下面程式碼:
console.log(Object.getPrototypeOf(p1) === Person.prototype);//false
console.log(Object.getPrototypeOf(p1));//null
console.log(Object.getPrototypeOf(p2) === Person.prototype);//true
console.log(Object.getPrototypeOf(p2));//{constructor: ƒ, sayName: ƒ}
p1
的原型被設定為了null
,獲取的結果也就是null
。p2
正常獲取到了原型。
本文參考《JavaScript高階程式設計(第三版)》