覆盖javascript方法

ein*_*ein 1 javascript oop

我是javascript的OOP新手.当我想覆盖一个方法时,我无法做到正确.我在下面举例说明了我的问题.也在http://jsfiddle.net/sRyQA/

function myGeometryObject(r, x, y){

    this.r = r;
    this.x = x;
    this.y = y;

    var OBJ = this;

    this.returnArea = function(){
        return 'wrong override';
    }
}

function myRectangle(r, x, y){
    myGeometryObject.call(this, r, x, y);
}
myRectangle.prototype = new myGeometryObject();

myRectangle.prototype.returnArea = function(){
    return 'right override';//I want JS to use this method
}
var rectangle = new myRectangle(0, 5, 5);
alert(rectangle.returnArea());
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 8

问题是

this.returnArea = function(){
    return 'wrong override';
}
Run Code Online (Sandbox Code Playgroud)

将设置该特定实例的属性(因为您在新实例上正确调用父的构造函数MyRectangle),这将"覆盖"所有继承的方法.

你的原型链看起来像这样:

 +------------------+        +------------------+        +------------------+
 | MyRectangle      |        | MyRectangle      |        | MyGeometry       |
 | instance         |------->| prototype        |------->| prototype        |
 |                  |        |                  |        |                  |
 | wrong returnArea |        | right returnArea |        |                  |
 +------------------+        +------------------+        +------------------+
                             (MyGeometry instance)
Run Code Online (Sandbox Code Playgroud)

retunArea实例中的方法是您在MyGeometryObject构造函数中指定的方法,而原型中的方法是您已覆盖的方法.

但是,如果你指定这个方法MyGeometryObjectprototype

function MyGeometryObject(r, x, y) { 
    this.r = r;
    this.x = x;
    this.y = y;    
}

MyGeometryObject.prototype.returnArea = function(){
    return 'wrong override';
}
Run Code Online (Sandbox Code Playgroud)

然后它会起作用,因为正确的returnArea方法将在原型链中更早出现:

 +------------------+        +------------------+        +------------------+
 | MyRectangle      |        | MyRectangle      |        | MyGeometry       |
 | instance         |------->| prototype        |------->| prototype        |
 |                  |        |                  |        |                  |
 |                  |        | right returnArea |        | wrong returnArea |
 +------------------+        +------------------+        +------------------+
                             (MyGeometry instance)
Run Code Online (Sandbox Code Playgroud)

附加说明:

  • 构造函数名称应以大写字母开头.
  • 如果以MyRectangle这种方式设置原型,还应该将constructor属性设置回MyRectangle:

    MyRectangle.prototype = new MyGeometryObject();
    MyRectangle.prototype.constructor = MyRectangle;
    
    Run Code Online (Sandbox Code Playgroud)