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做什么:它必须将数组的一个元素作为参数,然后用它做一些事情。在您的情况下,您想要执行该元素的方法。

调用方法并将应调用的对象作为参数传递的一种方法是使用.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 回答