要展开的意大利面条JavaScript代码

要展开的意大利面条JavaScript代码,javascript,coding-style,Javascript,Coding Style,我写了这样的东西: window.onload = function() { var a = new A(); a.init(); }; A = function() { this.b = {}; }; A.prototype = { init : function() { document.writeln("init"); this.b = new B(); this.b.doCallback(this.init

我写了这样的东西:

window.onload = function() {
    var a = new A();
    a.init();
};

A = function() {
    this.b = {};
};
A.prototype = {
    init : function() {
        document.writeln("init");
        this.b = new B();
        this.b.doCallback(this.init2);
    },

    init2 : function() {
        document.writeln("init2");
        this.b.say();
    }
};

B = function(){};
B.prototype = {
    doCallback: function(callback){
        callback();
    },

    say: function(){
        document.writeln("I'm B");
    }
};
init
init2
I'm B
对于我来说,输出应该如下所示:

window.onload = function() {
    var a = new A();
    a.init();
};

A = function() {
    this.b = {};
};
A.prototype = {
    init : function() {
        document.writeln("init");
        this.b = new B();
        this.b.doCallback(this.init2);
    },

    init2 : function() {
        document.writeln("init2");
        this.b.say();
    }
};

B = function(){};
B.prototype = {
    doCallback: function(callback){
        callback();
    },

    say: function(){
        document.writeln("I'm B");
    }
};
init
init2
I'm B
但是相反,它看起来是这样的:

init
init2

Chrome表示“say”方法未定义。有人能解释一下原因吗?

这是因为在你的代码中,这个并不代表B的一个实例

函数的this关键字在JavaScript中的行为稍有不同 与其他语言相比。两者之间也有一些区别 严格模式和非严格模式。通常,对象绑定到此 在当前范围内,由当前函数的运行方式决定 调用时,它不能在执行期间通过赋值进行设置,并且可以 每次调用函数时都会发生变化。ES5引入了bind 方法来修复函数的this,而不管它是如何调用的

因此,当您调用
callback
init2
时,
this.b
null
,并且没有任何
say
方法

如果您使用的是jQuery,那么可以使用proxy方法


更改
this.b.doCallback(this.init2)
this.b.doCallback(this.init2.bind(this.b))啊,对不起。应该是
this.init2.bind(this)
quirksmode不是关于
this
关键字的最佳参考,最好链接到感谢。我将
this
传递给
doCallback
,然后调用
this.init2()。虽然不那么优雅,但它很管用。