If I call myRobot.Speak.sayHi() it always returns undefined. Please, what am I doing wrong? Thanks for reply!
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’
3 Answers 3
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;
}
Rather then returning a new robot, make sure to bind all the methods in your powers to the robot.
To avoid hard coding in the loops try this:
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;
}
This relies on Function.prototype.bind so use the ES5 shim or use underscore for supporting old browsers (IE<9)
answered Jun 4, 2011 at 0:41
Raynos
170k57 gold badges359 silver badges399 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
myRobot.Speak.name = 'Robin';
In your case, this refers to Robot.Speak, not the parent object Robot.
3 Comments
Emmitt Gregory
Thanks for reply! Should I use
apply or call?Emmitt Gregory
But... I would like to access variable
myRobot.name from myRobot.Speak.sayHi. :-| Is it even possible?icktoofay
@Emmitt: Yes, it's possible, but it may make your code a little more complex.
insert name : this.name before the line sayHi: function() { and then it should work
answered Jun 4, 2011 at 0:33
AsherMaximum
9722 gold badges11 silver badges17 bronze badges
lang-js
undefined. That's not a problem at all in this case.