在JavaScript建立對象(二)——構造函數模式中,咱們說過可使用對象的constructor
屬性判斷對象的類型:p1.constructor === Person
,可能當時就有細心的讀者會想,咱們並無給這個對象添加過constructor
,這個屬性是從哪兒來的呢?講過原型以後,咱們知道這個屬性是原型中的,因此通常重寫原型時也都會把constructor
補上。javascript
咱們能夠經過像下面的代碼同樣,切斷實例與原型的關係:java
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
區分對象的類型。this
以前咱們還使用過instanceof
判斷對象的類型,該方法不只能夠判斷對象自己的類型,還能判斷出父類型,其實這個關鍵字也是依賴原型的。仍是以上述p1
爲例,看下面代碼:prototype
console.log(p1 instanceof Person);//false console.log(p1 instanceof Object);//false
如代碼所示,p1
的原型被置爲null
後,instanceof
也失效了。設計
這是原型對象上的一個方法,用於判斷對象的原型。那麼問題又來了,咱們明明重寫了Person
的原型,而且也沒有聲明isPrototypeOf()
方法,這個方法是從哪來的呢?這就涉及到原型鏈的知識了,之後再講。仍然以上述p1
、p2
爲例,看下面代碼:code
console.log(Person.prototype.isPrototypeOf(p1));//false console.log(Person.prototype.isPrototypeOf(p2));//true
如代碼所示,p1
切斷了與原型的關係,結果爲false
。p2
的原型就是Person.prototype
,結果爲true。對象
這是Object
上的一個方法,能夠直接獲取到實例的原型對象,看下面代碼:ip
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高級程序設計(第三版)》