2017-02-09 109 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