2014-07-25 84 views
3

每當我重新定義函數的原型並創建它的新對象時,其構造函數就會開始指向根對象函數而不是函數本身。讓我用情景解釋:對象函數在重新定義自定義函數的原型後指向對象函數

var Person=function(firstName,lastName) 
{ 
    this.firstName=firstName; 
    this.lastName=lastName; 
} 

Person.prototype.getFullName=function() 
{ 
    return this.firstName+" "+this.lastName; 
} 
var student=new Person("Ankur","Aggarwal"); 
student.constructor //shows Person which is correct 

之後,如果我重新定義了人物原型創造的改變

Person.prototype={} 
var manager=new Person('John','Smith'); 
manager.constructor // Points to Object. Why? 

也是一個新的對象,如果它指向的對象不是人,怎麼來的它有權訪問像firstName和lastName這樣的Person屬性?

enter image description here

回答

2

由於構造:

var Person=function(firstName,lastName) 
{ 
    this.firstName=firstName; 
    this.lastName=lastName; 
} 

它有一個默認的原型屬性,它是一個對象,其構造屬性引用構造。這個屬性(默認情況下)通過[[Prototype]]鏈繼承。

當你創建一個實例,在的firstNamelastName的屬性上的實例定義,彷彿:

var person = {firstName:..., lastName:...}; 

因此獲得這些屬性是通過構造函數的原型不受影響。

當一個新的對象被分配到構造函數的原型:

Person.prototype = {}; 

Object.prototype中(這是它的構造函數)繼承了一個構造財產。因此,訪問實例的構造函數首先在實例上查找,然後在其[[Prototype]](Person.prototype)上,然後在其[[Prototype]](Object.prototype)上查找並引用對象。您可以修復,通過這樣做:

Person.prototype.constructor = Person; 

你可以找到關於MDN的更多信息:Inheritance and the prototype chain

2

構造一個對象不會將其constructor屬性設置爲構建它的函數。相反,函數的默認值prototype使用指向該函數的constructor屬性進行初始化,該函數構造的對象從原型繼承constructor屬性。

當您替換函數的prototype時,替換不會自動獲得分配給它的constructor屬性的該函數。相反,新的prototype繼承constructor原型,即Object.prototype。因此,該函數創建的對象現在將繼承其原始模型Object.prototype中的Objectconstructor