3

これは OOP での最初の試みなので、ご容赦ください。

(function(){

  var Ship = function(){
    this.passengers = [];
    this.hasAliens = function() {
      return this.passengers.some(function(passenger){
         return passenger.isAlien()
      });
    }        
  }; 

  var Passenger = function(){};
  Passenger.prototype.isAlien = function(){
    return this instanceof Alien;
  };
  Passenger.prototype.board = function(ship) {
    ship.passengers.push(this)
  }

  var Alien = function() { Passenger.call(this); }
  var Human = function() { Passenger.call(this); }
  Alien.prototype = Object.create(Passenger.prototype);
  Human.prototype = Object.create(Passenger.prototype);
  Alien.prototype.constructor = Alien.constructor;   
  Human.prototype.constructor = Human.constructor;  

  var ship = new Ship();   
  var john = new Human();
  var zorg = new Alien();

  //simple testing
  john.board(ship);
  console.log("Ship does not have aliens ", ship.hasAliens()===false);
  zorg.board(ship);
  console.log("Ship has aliens ", ship.hasAliens()===true);

})();

</p>

これはうまくいきます。Passenger.isAlien()ただし、その厄介なネストされた無名関数を保存するためにメソッドを渡す方法を知りたいです。私はこのようにしようとしています:

  var Ship = function(){
    this.passengers = [];
    this.hasAliens = function(){
      return this.passengers.some(Passenger.isAlien);          
    };
  };

しかし、それは私に与えます"undefined is not a function"

http://jsfiddle.net/WYyxY/

4

2 に答える 2

1

私が言ったように、isAlienはプロトタイプのプロパティ、つまりコンストラクタ関数のインスタンスであり、コンストラクタ関数自体ではありません。Passenger.isAlienは実際には未定義です(コードのどこにもありませんPassenger.isAlien = function....)。

これを行うためのより簡潔な方法は実際にはありません。渡されたコールバックが何をしているのか考えてみてください.some。配列の要素を引数として取り、それを使って何かをしなければなりません。あなたの場合、その要素のメソッドを実行したいとします。

メソッドを呼び出して、呼び出すオブジェクトをパラメーターとして渡す方法の 1 つは、.call [MDN]を使用することです。残念ながら、JavaScript のすべての関数と同様に、 への参照を取得することはできません。これは、そのコンテキストが失われるPassenger.prototype.isAlien.callためです.call(どの関数を参照しているかがわからないため)。Passenger.prototype.isAlien最初にバインドする必要があります

this.passengers.some(
    Passenger.prototype.isAlien.call.bind(Passenger.prototype.isAlien)    
);

そして個人的には、それはもっと読みにくいと思います。

匿名関数に固執すると、あなたの意図はより明確になります。または、必要に応じて、別の関数にその関数を作成させることができます。

function callOn(funcName) {
    return function(obj) {
        return obj[funcName]();
    };
}

this.passengers.some(callOn('isAlien'));
于 2012-12-04T07:17:29.620 に答える
0

JavaScript で OOP を行うには、prototypeJSを確認することを強くお勧めします。コードがより読みやすくなり、継承もサポートされます!

ここで簡単に見てみましょう

于 2012-12-04T07:24:31.690 に答える