JavaScript原型问题

时间:2011-06-04 00:14:43

标签: javascript

如果我致电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’

3 个答案:

答案 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() {然后它应该可以正常工作