【问题标题】:Why is `this` losing its bind to my object?为什么 `this` 失去了与我的对象的绑定?
【发布时间】:2012-12-14 03:26:28
【问题描述】:

我正在尝试创建一个递归方法,但它正在失去与this 的绑定。这是重现我的问题的最简单方法:

var Foo = function() {
    return {
        foo : 'foo',
        bar : function() {
            co​nsole.log(this.foo);
            setTimeout(this.bar, 500);
        }
    }​;
}
var foo = new Foo();
foo.bar();​

这只会运行两次。第一次它会将foo 记录到控制台,第二次它将记录undefined。当然,它不会再运行了,因为bar 不再是this 的属性,因为我假设它被重置为全局对象。

我在bar 方法中尝试了var that = this,并引用了that.foo 和that.bar,但它并没有改变任何东西。我还在return 声明上方尝试了var that = this,但问题仍然存在。

预期结果:

富

富

富

富

...等等

这是一个示例 http://jsfiddle.net/k2hTJ/,它会导致:

富

未定义

【问题讨论】:

  • 因为this在函数范围内被覆盖了。
  • 我们应该为 that = this、self = this 的难题想出一个名字,这个难题似乎每天都困扰着 JavaScript 开发人员。
  • 从你的代码看起来,我推断你正在学习模块模式。太棒了,但如果你不介意我迂腐的话:在这种情况下,原型方法可能更合适,因为现在你正在为每个新实例创建一个新的函数对象......所有bar 属性都是单独的对象做同样的事情。这并不理想。如果您不想增加原型,当然也可以使用闭包
  • 你能帮我用模块模式发一下上面的代码吗?

标签: javascript recursion this javascript-objects


【解决方案1】:

setTimeout 将在当前范围内调用它的函数,但将this 作为全局对象。

解决此问题的最佳方法是执行以下操作:

var that = this;
setTimeout(function() {that.bar.apply(that);},500);

【讨论】:

  • @Alexander 在匿名函数this 作用域发生了变化
  • 啊谢谢!前几天我读到了关于 call and apply 的信息,一定是太不知所措了。
  • @Ibu,Elias Van Ootegem,你最好再读一遍。匿名函数中没有逻辑
  • @ibu:没关系:that.bar() 调用函数对象,在that 的上下文中由bar 引用,匿名函数中的任何this 引用都无关紧要。如果它确实重要,那么全局范围内的someObject.bar() 将意味着this 也将指向此处的全局对象(它没有)
  • @Alexander:当然有......申请不是 IMO 所必需的,但它也无害。我省略括号是错误的(考虑尼克的回答)
【解决方案2】:

这行得通:

var Foo = function() {
    return {
        foo : 'foo',
        bar : function() {
            co​nsole.log(this.foo);
            setTimeout(this.bar(), 500); //Add '()'
        }
    }​;
}
var foo = new Foo();
foo.bar();​

【讨论】:

  • 它可能工作得很好,但它不会做同样的事情:这会在半秒后调用方法的返回值,而不是方法本身
  • 恭喜。你刚刚创建了一个无限循环!
【解决方案3】:
foo = {
    foo: 'bar',
    bar: function() {
        console.log(foo.foo);
        setTimeout(foo.bar, 500);
    }
};
foo.bar();​

这也可以解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多