如何在javascript中从超类中扩充方法

时间:2013-12-06 02:03:16

标签: javascript oop object inheritance methods

我在基类中有一个方法,我想保留在子类中,但只是添加它。我发现了许多关于使用属性和方法扩充类和对象的东西,但是我找不到或者不理解如何只是扩充方法。最糟糕的情况是我必须将父类的整个方法粘贴到子类中,但这似乎是重复的代码...请帮助

function someObject (){
    this.someProperty = 1;
    this.incrementProperty = function incrementProperty(){   
        this.propertyOfSomeObject += 1;
    }
}

function newObject (){
    someObject.call(this);
    this.incrementProperty =  function incrementProperty(){
        //do everything the super class has for this property already
        return this.someProperty;
    }
}

var incrementer = new newObject;
alert (incrementer.incrementProperty()); //I want output to be 2

4 个答案:

答案 0 :(得分:4)

// parent object
function someObject () {
    this.someProperty = 1;
}

// add incrementProperty to the prototype so you're not creating a new function
// every time you instantiate the object
someObject.prototype.incrementProperty = function() {   
  this.someProperty += 1;
  return this.someProperty;
}

// child object
function newObject () {
    // we could do useful work here
}

// setup new object as a child class of someObject
newObject.prototype = new someObject();
// this allows us to use "parent" to call someObject's functions
newObject.prototype.parent = someObject.prototype;
// make sure the constructor points to the right place (not someObject)
newObject.constructor = newObject;

newObject.prototype.incrementProperty = function() {
    // do everything the super class has for this property already
    this.parent.incrementProperty.call(this);
    return this.someProperty;
}

var incrementer = new newObject();
alert (incrementer.incrementProperty()); // I want output to be 2

请参阅:http://jsfiddle.net/J7RhA/

答案 1 :(得分:1)

这应该做,你必须使用原型来实现一个真实的oo概念

function someObject (){
    this.someProperty = 1;
    this.propertyOfSomeObject = 0;
    this.incrementProperty = function incrementProperty(){   
        this.propertyOfSomeObject += 1;
        return this.propertyOfSomeObject;
    }
}

function newObject (){
    someObject.call(this);
    this.incrementProperty =  function incrementProperty(){
        this.__super__.incrementProperty.apply(this);
        return this.propertyOfSomeObject + 1;
    }
}

newObject.prototype = new someObject()
newObject.prototype.__super__ = newObject.prototype

var incrementer = new newObject();
alert(incrementer.incrementProperty()); //I want output to be 2

实验从newObject中删除incrementProperty,它将返回1

答案 2 :(得分:1)

我通常使用augment库在JavaScript中编写类。这就是我使用augment

重写代码的方法
var Foo = Object.augment(function () {
    this.constructor = function () {
        this.someProperty = 1;
    };

    this.incrementProperty = function () {
        this.someProperty++;
    };
});

var Bar = Foo.augment(function (base) {
    this.constructor = function () {
        base.constructor.call(this);
    };

    this.incrementProperty = function () {
        base.incrementProperty.call(this);
        return this.someProperty;
    };
});

Bar扩展Foo以来,您可以看到Foo.prototype作为参数(我们称之为base)。这使您可以轻松调用基类constructorincrementProperty函数。它还表明constructor本身只是原型上定义的另一种方法。

var bar = new Bar;

alert(bar.incrementProperty());

预期输出为2。请亲自查看演示:http://jsfiddle.net/47gmQ/

答案 3 :(得分:0)

来自this answer

覆盖功能

有时children需要扩展parent个功能。

你希望'child'(= RussionMini)做一些额外的事情。当RussionMini可以调用Hamster代码执行某些操作然后执行额外操作时,您不需要将Hamster代码复制并粘贴到RussionMini。

在下面的例子中,我们假设一只仓鼠可以每小时跑3公里,但Russion迷你只能跑一半。我们可以在RussionMini中硬编码3/2,但如果要更改此值,我们在代码中需要更改多个位置。以下是我们如何使用Hamster.prototype获得父(仓鼠)速度。

// from goog.inherits in closure library
var inherits = function(childCtor, parentCtor) {
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.prototype.constructor = childCtor;
};


var Hamster = function(name){
 if(name===undefined){
   throw new Error("Name cannot be undefined");
 }
 this.name=name;
}
Hamster.prototype.getSpeed=function(){
  return 3;
}
Hamster.prototype.run=function(){
  //Russionmini does not need to implement this function as
  //it will do exactly the same as it does for Hamster
  //But Russionmini does need to implement getSpeed as it
  //won't return the same as Hamster (see later in the code) 
  return "I am running at " + 
    this.getSpeed() + "km an hour.";
}

var RussionMini=function(name){
  Hamster.apply(this,arguments);
}
//call this before setting RussionMini prototypes
inherits(RussionMini,Hamster);

RussionMini.prototype.getSpeed=function(){
  return Hamster.prototype
    .getSpeed.call(this)/2;
}    

var betty=new RussionMini("Betty");
console.log(betty.run());//=I am running at 1.5km an hour.