开发者

JavaScript prototype problem

开发者 https://www.devze.com 2023-03-10 03:04 出处:网络
If I call myRobot.Speak.sayHi() it always returns undefined. Please, what am I doing wrong? Thanks for reply!

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’


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)


myRobot.Speak.name = 'Robin';

In your case, this refers to Robot.Speak, not the parent object Robot.


insert name : this.name before the line sayHi: function() { and then it should work

0

精彩评论

暂无评论...
验证码 换一张
取 消