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;

このコードは期待どおりに機能します。同じ数kmの走行を呼び出した後、効率的な車にはより多くの燃料が残っています。しかし、オーバーライドされた子バージョン内で関数の親バージョンを使用したいと思います。このようなもの:

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

クラスのようにこれを達成する方法はありますか?CarEfficientCar クラスの中にほとんどすべてのものを入れたいのですが、申し訳ありませんが、関数です。

4

3 に答える 3

2

javascriptで継承を使用したい場合は、JohnResigのこの小さな宝石を使用することをお勧めします。

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()のシムを使用して、このようにします。

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 に答える