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

如何在javascript中将对象方法传递给数组方法,javascript,oop,Javascript,Oop,这是我第一次尝试OOP,所以请容忍我: (function(){ var Ship = function(){ this.passengers = []; this.hasAliens = function() { return this.passengers.some(function(passenger){ return passenger.isAlien() }); } }; var Pas

这是我第一次尝试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);          
    };
  };
但这让我明白了“未定义的不是函数”


正如我所说,
isAlien
是原型的属性,即构造函数的实例,而不是构造函数本身
Passenger.isAlien
确实是未定义的(代码中没有任何地方是
Passenger.isAlien=function….

没有比这更简洁的方法了。想想一个回调传递给
。一些
正在做什么:它必须把数组的一个元素作为参数,然后对它做一些事情。在本例中,您希望执行该元素的方法


调用方法并将其作为参数调用的对象传递的一种方法是使用。不幸的是,与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'));

对于使用javascript进行OOP,我强烈建议您签出。您的代码变得更加可读,并且还支持继承


下面是一个例子

您的代码中有一些缺陷。例如,
Alien.prototype=Object.create(乘客)应该是
Alien.prototype=Object.create(Passenger.prototype)
而不是在
Passenger
构造函数中分配函数,您应该将它们分配给
Passenger.prototype
。关于您的问题:之所以会出现错误,是因为
isAlien
是构造函数实例的属性,而不是构造函数本身。没有比使用匿名函数更简洁的方法了。谢谢你的帮助,我已经重构了代码。您如何看待顶级
isAlien=function(passenger){…}
然后允许
返回这个.passengers.some(isAlien)
Passenger.prototype.isAlien=isAlien
Passenger.prototype.isAlien=isAlien
无法按预期工作
isAlien
在本例中接受一个参数,因此
john.isAlien()
将通过一个错误,因为函数中未定义
passenger
。这基本上是同一个问题,但反之亦然。您必须调用
john.isAlien(john)
,这也不简单。但是如果您执行
if(!alien)alien=this
之类的操作,那么我可以提供上下文no。但我仍然不确定它是否更具可读性。感谢indieman,我知道一些库可以帮助我做到这一点,但我想用straight js进行尝试。JavaScript本机支持继承。只是说,因为你让它听起来好像不是。