如何在javascript中将对象方法传递给数组方法

时间:2012-12-04 06:58:34

标签: javascript oop

这是我对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);

})();

这很好用。但是,我想知道如何通过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/

2 个答案:

答案 0 :(得分: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'));

答案 1 :(得分:0)

为了使用javascript进行OOP,我强烈建议您查看prototypeJS。您的代码变得更易读,它也支持继承!

这是一个quick look