2017-02-09 108 views
0

當我們使用「new」運算符爲javascript中的對象創建實例時會發生什麼?並且,在創建過程中,何時分配了構造函數的原型? 我嘗試動態地分配在構造一個新的原型,但結果頗爲怪異:在構造函數中動態賦值原型不起作用

function Person(name, age){//the super class constructor 
    this.name = name; 
    this.age = age; 
    if (typeof this.sayName != "function") {//set the function in prototype so Person's instance or subType can share just one instance of function(since function in javascript is Object indeed) 
     Person.prototype.sayName = function(){ 
      console.log("my name is ", this.name); 
     } 
    } 
} 
//if I assign Student's prototype here, not in its constructor, it will be OK, but why not encapsulate it within the constructor if I can? 
//Student.prototype = new Person(); 
function Student(name, age, school, grade){//the subType constructor 
    Person.call(this, name, age);//get the super class property 
    this.school = school;//init the subType property 
    this.grade = grade; 
    if (!(Student.prototype instanceof Person)) {//just assign the prototype to Student for one time 
     Student.prototype = new Person(); 
    } 
} 

let person1 = new Student("Kate", 23, "Middle school", "3.8"); 
let person2 = new Student("Gavin", 23, "Middle school", "3.8"); 
let person3 = new Student("Lavin", 23, "Middle school", "3.8"); 
person1.sayName();//Uncaught TypeError: person1.sayName is not a function 
person2.sayName();//my name is Gavin 
person3.sayName();//my name is Lavin 
  1. 自「sayName()」可以分配到人的原型,我們可以得出結論,原型已經準備好當構造函數代碼執行
  2. 基於第1點,在構造函數Student()中,爲什麼我無法替換原始原型?(person1將找不到sayName函數)
  3. 當構造函數的原型被分配了嗎?我可以在哪裏更換默認原型?
+0

@smarber,感謝您的解釋和鏈接「http://stackoverflow.com/a/17393153/1507546」。但實際上我迷惑了爲什麼person1無法獲得sayName方法,而person2和person3可以?當我們新建一個對象時,我對後面的場景感到好奇。 – blueGhost

+0

你應該評論他的帖子,而不是你的帖子,否則他不會得到通知。 :) –

回答

0

當我們用 「新」 運營商在JavaScript的對象創建一個實例,會發生什麼?

繼MDN文檔,你的情況:

當代碼新的學生(...)執行第一次,下面的事情發生:

  1. '的新對象創建,繼承自Student.prototype
  2. 構造函數Student用指定的參數調用,並且綁定到新創建的對象上...

基本上,你不能在構造函數中改變第一個實例的原型。它已被設置爲Student.prototype。您可以從任何地方調用設置原型代碼,但在開始創建新實例之前。

下一個實例將使用Person原型創建。

+0

謝謝!我檢查了MDN文件,現在明白了。鏈接「https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new」 – blueGhost

0

function Person(name, age, parents){//the super class constructor 
 
\t this.name = name; 
 
\t this.age = age; 
 
} 
 

 
// This is must be outside the constructor/function Person 
 
Person.prototype.sayName = function(){ 
 
\t console.log("my name is ", this.name); 
 
} 
 

 
// Is Student created inside Student constructor? 
 
//Student.prototype = new Person(); 
 
function Student(name, age, school, grade){//the subType constructor 
 
\t Person.call(this, name, age);//get the super class property 
 
\t this.school = school;//init the subType property 
 
\t this.grade = grade; 
 
} 
 

 
// Check this to understand why this is a good way to inherit in js http://stackoverflow.com/a/17393153/1507546 
 
Student.prototype = Object.create(Person.prototype); 
 

 
let person1 = new Student("Kate", 23, "Middle school", "3.8"); 
 
let person2 = new Student("Gavin", 23, "Middle school", "3.8"); 
 
let person3 = new Student("Lavin", 23, "Middle school", "3.8"); 
 
person1.sayName();//Uncaught TypeError: person1.sayName is not a function 
 
person2.sayName();//my name is Gavin 
 
person3.sayName();//my name is Lavin

+0

感謝您的解釋和鏈接「stackoverflow.com/a/17393153/1507546」;剛纔我檢查了MDN文件,現在得到了答案。因爲「爲什麼person1無法獲得sayName方法,而person2和person3可以?並且當我們新建一個對象時,我對後面的場景感到好奇」 – blueGhost