13

私の用語は少しずれているので、必要に応じて自由に修正してください。javascript と「基本クラス」で関数をオーバーロードして、オーバーロードされたメソッドと継承されたクラスを利用して、基本クラスのメソッドにアクセスしたいと考えています。これまでのところ、 と オブジェクト リテラルの (動作する) 組み合わせを考え出しましたjquery.extend()が、これは見栄えがよくありません。これを行うためのより良い方法があるかどうか疑問に思っていました(jqueryを使用できます)。

var Base = new function(args, m) {
   $.extend(this, m);
   var self = this;
   this.bar = function() {
     self.foo();
   }
   this.foo = function() {
     self.blah();
   }
   this.dosomething = function() {}
};

var Child = function(arg1) {
   $.extend(this, new Base(args, {
     blah: function() {
       self.dosomething()
     }
   }));
}
4

2 に答える 2

20

あなたが探しているのは、オブジェクト間で機能を共有する方法です。これはまさに、JavaScript プロトタイプの継承モデルが得意とする類のものです。

これを実現するために jQuery やその他のライブラリを使用する必要はありません。言語のやり方に従うことを検討してください。

プロトタイプ

JavaScript では、オブジェクトには「プロトタイプ」があります。JavaScript がメソッドを持たないオブジェクト内のメソッドを探すとき、プロトタイプの「チェーン」でそれを探します。したがって、必要なのは、そのチェーンの下位レベルでその機能をオーバーライドすることだけです。

これについては、MDN のチュートリアルで詳しく説明されています。

あなたの特定のケース

オーバーライドする必要があるメソッドを持つandBaseクラスChildが必要な場合は、そのチェーンの下位のどこかに割り当てるだけです。BaseChild

調べる順番は

Child Object --> Child's prototype (a Base object) --> Base's prototype (an Object)

たとえば、クラス Base があるとしましょう

function Base(){

}
Base.prototype.bar = function() {
     //bar logic here
     console.log("Hello");
};
Base.prototype.foo= function() {
     //foo logic here
};

Function Child(){

}

Child.prototype = new Base();

Child に別の方法で Bar を実装してもらいたいのですが、その場合は実行できます

Child.prototype.bar = function(){
   console.log("World");
}

その結果、

var a = new Base();
a.bar(); //outputs "Hello" to the console
var b = new Child();
b.bar(); //outputs "World" to the console
         //The Base instance that is the prototype of b has the bar method changed above

JavaScript の抽象クラスに関する注意

古典的な継承に基づく言語 (Java など) で抽象メソッドの継承が使用される主な理由の 2 つは、ポリモーフィズムとコード共有です。

JavaScript ではどちらも問題ありません。コード共有は、プロトタイプの継承を使用して簡単に行うことができます。さらに、ほぼすべての関数を別のコンテキストで実行できます。たとえば、空の配列でオブジェクトのbarメソッドを呼び出すこともできます。Childb.bar.call([])

ポリモーフィズムに関しては、JavaScript はダックタイピングを備えた動的言語です。これは、宣言された方法ではなく、能力に基づいてオブジェクトを見ることを意味します。いくつかのオブジェクトに呼び出されたメソッドがある場合、それらが配列または他のコレクションにある場合、それらのそれぞれでそのメソッドを問題なくbar呼び出すことができます。共通のインターフェース、タイプ、または祖先を必要とする Java では。

これらの理由から、抽象クラスなどは JavaScript では大きな役割を果たしません。

于 2013-03-09T01:18:15.463 に答える
2

CoffeeScriptと同じ方法で行うことをお勧めします。varコードの見栄えを良くするために、最初の宣言を別のファイルに入れることができます。私の知る限り、__extends同等です$.extends

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };


var Fruit = (function() {

  function Fruit() {
    console.log("New fruit");
  }

  return Fruit;

})();

var Apple = (function(_super) {

  __extends(Apple, _super);

  function Apple() {
    console.log("New apple");
    Apple.__super__.constructor.apply(this, arguments);
  }

  return Apple;

})(Fruit);

var apple = new Apple();

または、CoffeeScript を使用できる場合は、次のようになります。

class Fruit
  constructor: ->
    console.log "New fruit"

class Apple extends Fruit
  constructor: ->
    console.log "New apple"
    super
于 2013-03-09T01:15:53.330 に答える