如果我致电myRobot.Speak.sayHi()
,它始终会返回undefined
。拜托,我做错了什么?谢谢你的回复!
var Factory = (function() {
// Constructor
var Robot = function() {
};
// Public
return {
extendRobot: function(power, methods) {
Robot.prototype[power] = methods;
},
createRobot: function() {
return new Robot();
}
};
}());
Factory.extendRobot('Speak', {
sayHi: function() {
return 'Hi, ' + this.name;
}
});
var myRobot = Factory.createRobot();
myRobot.name = 'Robin';
myRobot.Speak.sayHi() // => ‘Hi, Robin’
答案 0 :(得分:2)
myRobot.Speak.name = 'Robin';
在您的情况下,this
引用Robot.Speak
,而不是父对象Robot
。
答案 1 :(得分:2)
createRobot: function() {
var r = new Robot();
for (var k in r.Speak) {
if (typeof r.Speak[k] === "function") {
r.Speak[k] = r.speak[k].bind(r);
}
}
return r;
}
而不是返回一个新机器人,确保将所有权力方法绑定到机器人。
为避免循环中的硬编码,请尝试以下方法:
Robot.powers = [];
...
extendRobot: function(power, methods) {
Robot.powers.push(power);
Robot.prototype[power] = methods;
},
createRobot: function() {
var robot = new Robot();
Robot.powers.forEach(function(power) {
for (var method in robot[power]) {
if (typeof robot[power][method] === "function") {
robot[power][method] = robot[power][method].bind(robot);
}
}
});
return robot;
}
这取决于Function.prototype.bind,因此请使用ES5 shim或使用underscore来支持旧浏览器(IE <9)
答案 2 :(得分:0)
在行name : this.name
之前插入sayHi: function() {
然后它应该可以正常工作