簡體   English   中英

子類不能調用其父類的原型方法

[英]Child class can't call its parent's prototype method

我正在學習JS原型。

Java語言的角度來看,我希望, SpecificRectangle對象可以訪問area()方法,因為area()是其父(Rectangle類)原型的方法。

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);

總而言之,我無法在SpecificRectangle實例上調用area()方法。
標准JS錯誤得到:

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

這種封裝的解釋和原因是什么?

老實說,我不知道確切的原因,但你需要在構造函數之外設置原型:

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

這里的工作示例。


編輯 @herby的評論:

看來確實上面的方法可以打破原型繼承,這取決於如何構建超類構造函數(參見本文 )。

更強大的解決方案是使用Object.createsource - thanks herby)

// 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的更新示例

您應該復制基類原型。 例如:

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);
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM