1

我正在尝试以最简单的方式实现继承。我知道 JS 继承是基于原型的,但由于我更精通基于 OO 类的语言,我有点偏向于将“类”逻辑封装在“构造函数”函数中。我还试图避免在原型对象中定义新成员,因为该代码应该放在“类”函数之外。这是我尝试过的:

    function Car(color, year, plate) { 
        this.color = color;
        this.year = year;
        this.plate = plate;
        this.hasFuel = true;
        this.fuel = 100;    

        this.run = function(km) {
            this.fuel = this.fuel - km*this.getFuelConsumptionRate(); 
            if(this.fuel < 0){
                this.fuel = 0;
            }
            if(this.fuel == 0){
                this.hasFuel = false;
            }
        };  

        this.getFuelConsumptionRate = function(){
            return 4.2;
        };
    }

    function EfficientCar(color, year, plate, weight){
        //Emulating a super call
        Car.call(this, color, year, plate);

        this.weight = weight;

        //Overriden method
        this.getFuelConsumptionRate = function(){
            return 2.2;
        };  
    }
    //Inheritance 
    //(I don't like this out of the method, but it is needed for the thing to work)
    EfficientCar.prototype = Car;
    EfficientCar.prototype.constructor = EfficientCar;

此代码按预期工作:高效汽车在调用相同公里数后剩余的燃料更多。但现在我想在覆盖的子版本中使用函数的父版本。像这样的东西:

    function EfficientCar(color, year, plate, weight){
        //Emulating a super call
        Car.call(this, color, year, plate);

        this.weight = weight;

        this.getFuelConsumptionRate = function(){
            return super.getFuelConsumptionRate() / 2;  //If only I could do this...
        };  
    }

有没有办法以类方式实现这一目标?我希望几乎所有内容都包含在Carand EfficientCar classes中,对不起,函数。

4

3 回答 3

2

如果你想在 javascript 中使用继承,我建议你使用 John Resig 的这个小宝石:

http://ejohn.org/blog/simple-javascript-inheritance/

来自博客的示例:

var Person = Class.extend({
  init: function(isDancing){
    this.dancing = isDancing;
  },
  dance: function(){
    return this.dancing;
  }
});

var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }
});

var p = new Person(true);
p.dance(); // => true

var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true

// Should all be true
p instanceof Person && p instanceof Class &&
n instanceof Ninja && n instanceof Person && n instanceof Class
于 2013-01-14T12:51:30.767 回答
1

如果要调用“超类”中定义的函数,则应正确使用原型,即在原型上而不是在实例上定义函数:

Car.prototype.getFuelConsumptionRate = function() {
 return 4.2; 
}

和继承

EfficientCar.prototype = new Car();

然后,您将能够调用超级函数:

EfficientCar.prototype.getFuelConsumptionRate = function(){
   var superfun = this.constructor.prototype.constructor.prototype.getFuelConsumptionRate;
   return superfun.call(this) / 2;
};  

完整演示(打开控制台)

如果您将调用超级函数(我认为这是一个糟糕的函数)作为一种做法,那么您可以构建一个嵌入的小方法并缩短方法的获取。

如果您确切知道继承的目标级别,那当然更容易,因为您可以简单地替换

var superfun = this.constructor.prototype.constructor.prototype.getFuelConsumptionRate;

var superfun = EfficientCar.prototype.getFuelConsumptionRate;

请注意,javascript 与您似乎更习惯的其他语言并不完全相同。尝试应用外来模式通常会导致程序更冗长、更不灵活和更难维护。

于 2013-01-14T13:01:01.913 回答
0

我这样做,在 Object.create() 不受支持时使用 shim。

var Car = function() {
    // code
};

Car.prototype.getFuelConsumptionRate = function() {
    // code
};


var EfficientCar = function() {
    Car.call(this);
};

EfficientCar.prototype = Object.create(Car.prototype);

EfficientCar.prototype.getFuelConsumptionRate = function() {
    var result = Car.prototype.getFuelConsumptionRate.call(this)
    // code
};
于 2013-01-14T13:21:04.350 回答