在构造函数中动态分配原型不起作用

时间:2017-02-09 14:30:50

标签: javascript oop constructor prototype-programming

当我们使用“new”运算符在javascript中为Object创建实例时会发生什么?并且,在创建期间,何时分配构造函数的原型? 我尝试在构造函数中动态分配一个新的原型,但结果很奇怪:

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()”可以分配给Person的原型,所以我们可以断定原型在执行构造函数代码时已经准备好了
  2. 基于第1点,在构造函数Student()中,为什么我无法替换原始原型?(person1将找不到sayName函数)
  3. 何时分配了构造函数的原型?我在哪里可以替换默认原型?

2 个答案:

答案 0 :(得分:0)



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

// This is must be outside the constructor/function Person
Person.prototype.sayName = function(){
	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
	Person.call(this, name, age);//get the super class property
	this.school = school;//init the subType property
	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




答案 1 :(得分:0)

  

当我们使用" new"运算符在javascript中为对象创建实例?

关注您的案例的MDN文档:

  

第一次执行代码new Student(...)时,会发生以下情况:

     
      
  1. 创建一个新对象,继承自Student.prototype
  2.   
  3. 使用指定的参数调用构造函数Student,并将其绑定到新创建的对象...
  4.   

基本上,您无法在构造函数中更改第一个实例的原型。它已设置为Student.prototype。您可以从任何地方调用设置原型代码,但在开始创建新实例之前。

将使用Person原型创建下一个实例。