JavaScript中的构造函数和继承

时间:2010-03-19 17:34:00

标签: javascript oop inheritance prototype

这是关于JavaScript中的“继承”。

假设我创建了一个构造函数Bird(),另一个叫做Parrot(),我通过将它的实例分配给Parrot的原型来“继承”Bird的属性,如下面的代码所示:

function Bird() {
    this.fly = function(){};
}

function Parrot() {
    this.talk = function(){ alert("praa!!"); };
}
Parrot.prototype = new Bird();

var p = new Parrot();

p.talk(); // Alerts "praa!!"
alert(p.constructor); // Alerts the Bird function!?!?!

在我创建了一个Parrot实例之后,为什么它的.constructor属性是Bird(),而不是Parrot(),它是我用来创建对象的构造函数?

2 个答案:

答案 0 :(得分:3)

Prototype是一个对象,就像JavaScript中的任何其他对象一样,对象分配是通过引用。你刚刚给鹦鹉的原型分配了一只新鸟,所以鹦鹉的原型现在是鸟类的实例。鸟的建造者是伯德。

您可以使用

行修复此问题
Parrot.prototype.constructor = Parrot;

另一种方法是将Bird的原型克隆分配给Parrot.prototype

function deepClone(obj) {
    var clone = {};
    for(var i in obj) {
        if(typeof(obj[i])==="object") {
            clone[i] = deepClone(obj[i]);
        } else {
            clone[i] = obj[i];
        }
    }
    return clone;
}


Parrot.prototype = deepClone(Bird.prototype);
Parrot.prototype.constructor = Parrot;

我更喜欢这个因为:

1)它可以节省创建鸟类的任意实例(如果有多少鸟类被创造出来的话会怎么样)

2)如果Bird构造函数接受了在构造函数体中测试的参数,该怎么办?然后 打电话:

Parrot.prototype = new Bird();
然后

可能会导致空指针

答案 1 :(得分:1)

构造函数引用创建实例的原型(而不是实例)的函数。