如何在javascript中将对象方法传递给数组方法
这是我第一次尝试OOP,所以请容忍我:如何在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
(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本机支持继承。只是说,因为你让它听起来好像不是。