这是我对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"
答案 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