子类不能调用其父类的原型方法

时间:2011-12-28 12:52:03

标签: javascript inheritance methods call prototype-programming

我正在学习JS原型。

Java语言点我期望,SpecificRectangle对象可以访问area()方法,因为area()是其父(Rectangle类)原型的方法。 / p>

function Rectangle(w,h){
 this.width = w;
 this.height=h;
}
Rectangle.prototype.area = function(){return this.width*this.height}

function SpecificRectangle(w,h,angle){
  Rectangle.call(this,w,h);
  SpecificRectangle.prototype=new Rectangle();
}

var specrec = new SpecificRectangle(7,8,45);

总而言之,我无法在area()个实例上调用SpecificRectangle方法 标准JS错误得到了:

TypeError: specrec.area is not a function
[Break On This Error] specrec.area() 

这种封装的解释和原因是什么?

2 个答案:

答案 0 :(得分:3)

老实说,我不知道确切的原因,但你需要在构造函数之外设置原型:

function SpecificRectangle(w, h, angle) {
    Rectangle.call(this,w,h);
}

SpecificRectangle.prototype = new Rectangle();
SpecificRectangle.prototype.constructor = SpecificRectangle; // Otherwise instances of SpecificRectangle would have a constructor of Rectangle

工作示例here


@herby评论后

编辑

看来,上层方法确实可以打破原型继承,具体取决于构建超类构造函数的方式(参见this article)。

更强大的解决方案是使用Object.createsource - 谢谢她)

// in case Object.create does not exist
if (typeof Object.create !== 'function') {
    Object.create = function(o) {
        var F = function() {};
        F.prototype = o;
        return new F();
    };
}

function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}
Rectangle.prototype.area = function() {
    return this.width * this.height
}

function SpecificRectangle(w, h, angle) {
    Rectangle.call(this, w, h);
}

SpecificRectangle.prototype = Object.create(Rectangle.prototype);
SpecificRectangle.prototype.constructor = SpecificRectangle;

var r = new SpecificRectangle(100, 50, 30);
alert(r.area());

jsfiddle

上的更新示例

答案 1 :(得分:1)

您应该复制基类原型。例如:

function Rectangle(w,h){
    this.width = w;
    this.height=h;
}
Rectangle.prototype.area = function(){return this.width*this.height}

function SpecificRectangle(w,h,angle){
    Rectangle.call(this,w,h);
}
function SpecificRectangleProto(){}
SpecificRectangleProto.prototype = Rectangle.prototype;
SpecificRectangle.prototype = new SpecificRectangleProto();

var specrec = new SpecificRectangle(7,8,45);
alert(specrec.area);

我建议从某个框架中提取extend方法。例如ExtJS。 使用这种方法,您可以像这样扩展类:

SpecificRectangle = extend(Rectangle, {
    constructor: function(w,h,angle){
        SpecificRectangle.superclass.constructor.call(this,w,h);
    }
});