为什么我们需要在JavaScript继承中调用父构造函数

时间:2012-02-23 08:49:44

标签: javascript inheritance prototype

我正在尝试使用JavaScript继承。基本上,我正在关注this教程。

我看到,使用那里的代码,Person类被实例化两次。请查看this fiddle

我所做的是评论:

Person.call(this)

继承工作得很好。

在原始代码中,行

Person.call(this)

被使用。是否需要使用子范围调用父构造函数?

请您解释一下,我是OO JavaScript的新手。

非常感谢。

修改

我的小提琴代码如下:

function Person(gender) {
    this.gender = gender;
    document.write('Person instantiated</br>');
}

Person.prototype.walk = function(){
    document.write("is walking</br>");
};

Person.prototype.sayHello = function(){
    document.write("Hello</br>");
};

Person.prototype.sayGender = function(){
    document.write(this.gender + "</br>");
};



function Student() {
    //Person.call(this);
    document.write('Student instantiated</br>');        
}
Student.prototype = new Person();

Student.prototype.constructor = Student;

Student.prototype.sayHello = function(){
    document.write("Student says Hello</br>");
}
Student.prototype.sayGoodBye = function(){
    document.write("Student says goodbye</br>");
}


var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();

document.write(student1 instanceof Person);
document.write("</br>");
document.write(student1 instanceof Student);

3 个答案:

答案 0 :(得分:4)

是的,你需要它。在您的示例中,所有学生都具有相同的性别,并且只有一个人实例化,无论实例化学生的数量如何。

更好的是:

function Student() {
    // gives this Student properties of one (new) Person:
    Person.call(this);
    document.write('Student instantiated</br>');        
} 
// does not create a Person, just makes Students have Person prototype features
Student.prototype = Object.create(Person.prototype);

答案 1 :(得分:1)

运行您提供的示例仅在初始执行脚本期间调用Person()构造函数,行“Student.prototype = new Person();”被执行。

如果我们修改您的脚本以创建第二个学生并将设置与实例化分开:bit: http://jsfiddle.net/anacW/

function Person(gender) {
    this.gender = gender;
    document.write('Person instantiated</br>');
}

Person.prototype.walk = function(){
    document.write("is walking</br>");
};

Person.prototype.sayHello = function(){
    document.write("Hello</br>");
};

Person.prototype.sayGender = function(){
    document.write(this.gender + "</br>");
};



function Student() {
    //Person.call(this);
    document.write('Student instantiated</br>');        
}
Student.prototype = new Person();

Student.prototype.constructor = Student;

Student.prototype.sayHello = function(){
    document.write("Student says Hello</br>");
}
Student.prototype.sayGoodBye = function(){
    document.write("Student says goodbye</br>");
}

document.write("*** Building student1 *** </br>");
var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();

document.write("*** Building student2 ***</br>");
var student2 = new Student();
student2.sayHello();
student2.walk();
student2.sayGoodBye();

document.write("*** InstanceOf Tests ***</br>");
document.write("student1 is Person?: " + (student1 instanceof Person));
document.write("</br>");
document.write("student1 is Student?: " + (student1 instanceof Student));
document.write("</br>");
document.write("student2 is Person?: " + (student2 instanceof Person));
document.write("</br>");
document.write("student2 is Student?: " + (student2 instanceof Student));

此代码给出:

Person instantiated
*** Building student1 *** 
Student instantiated
Student says Hello
is walking
Student says goodbye
*** Building student2 ***
Student instantiated
Student says Hello
is walking
Student says goodbye
*** InstanceOf Tests ***
student1 is Person?: true
student1 is Student?: true
student2 is Person?: true
student2 is Student?: true

这表明Person构造函数只被调用一次,并且永远不会通过实例化Student来调用。在您的情况下这可能是可取的(我不知道足够的javascript来告诉您它是否是'正确'形式)。

答案 2 :(得分:-1)

这是我如何做到的:

Foo = function() {}
Foo.prototype.sayHello = function() { console.log("hello"); }

Bar = function() {}
Bar.prototype = new Foo();
Bar.prototype.sayBye = function() { console.log("bye"); }

var oBar = new Bar();
oBar.sayHello(); // "hello"
oBar.sayBye(); // "bye"