【问题标题】:Unexpected value for "this" when using namespaces [duplicate]使用命名空间时“this”的意外值[重复]
【发布时间】:2015-06-19 02:54:52
【问题描述】:

当用于 JavaScript 中的命名空间时,我似乎遇到了一些关于 this 的问题。具体来说,每当我通过setTimeoutsetInterval 调用命名空间函数时,我似乎不再使用this 的正确值。

例如,考虑以下代码:

var myNamespace = {
    myVar: 123,

    foo: function () {
        console.log('Inside foo');
        console.log('this.myVar = ' + this.myVar);
        console.log('myNamespace.myVar = ' + myNamespace.myVar);

        // This works excactly as expected, it prints 123 and 123
        this.bar();

        // This does not, it prints undefined and 123
        setTimeout(this.bar, 250);
    },

    bar: function () {
        console.log('Inside bar');
        console.log('this.myVar = ' + this.myVar);
        console.log('myNamespace.myVar = ' + myNamespace.myVar);
    }
}

myNamespace.foo();

bar 直接从foo 调用时,一切都会按我的预期工作:它会打印123123
但是,当从setTimeout 调用bar 时,它会打印undefined123

看来bar的第二种调用方式this的值不是我所期望的。我希望它是myNamespace,但它似乎是window


这让我想到了两个问题:

  1. 有没有办法让this 内的bar 值始终指向myNamespace,无论它是从哪里调用的?
  2. bar 内部硬编码myNamespace. 代替this. 是否更合适?

【问题讨论】:

    标签: javascript namespaces javascript-namespaces


    【解决方案1】:

    那是因为this 会根据作用域而变化,一种方法是绑定一个匿名函数:

    setTimeout(function(){this.bar()}.bind(this), 250);
    

    【讨论】:

    • 美化:setTimeout(this.bar.bind(this), 250);
    • 似乎将.bind(myNamespace) 添加到bar 的定义中也可以。有首选约定的标准吗?
    • 把它包装在一个函数中是什么意思?
    • 你也可以绑定方法来调用实例,这就是我说one way would be的原因。
    • 这个例子实际上并没有执行bar,即使执行了,匿名函数也完全没有必要(如果你没有bind,你需要捕获this通过关闭,你没有这样做)。更不用说这个问题无论如何都是一个骗局。
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 2016-01-03
    • 2015-07-21
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多