javascript - 更改 setTimeout 上的匿名函数的范围会导致奇怪的警告

标签 javascript scope

这纯粹是作为研究和个人发展让我感兴趣的。我有一组命名空间的函数/变量。

在 1 个函数中,我需要通过 setTimeout 调用另一个函数,但将范围保持为“this”。我有点挣扎,似乎无法在 setTimeout 运行时绑定(bind)它。

var foo = {
    ads: ["foo","bar"],
    timeDelay: 3,
    loadAds: function() {
        var al = this.ads.length;
            if (!al)
                return; // no ads

            for(var i = 0; i < al; i++) {
                setTimeout(function() {
                    this.scrollAd(this.ads[i]);
                }.apply(this), this.timeDelay * 1000);
            }
        },
        scrollAd: function(adBlock) {
            console.log(adBlock);

        }
    };
};

.apply(this) 确实改变了范围,因为 console.log 输出正确的对象,但它立即运行该函数,然后异常/警告出现,因为回调仍然为空:

useless setTimeout call (missing quotes around argument?)

有没有一种优雅的方式来做到这一点?我知道我能做到

var _this = this;

并在匿名回调中引用 _this。例如,在 mootools 中,我会使用 .bind(this) 代替......

不,因为这涉及到动画,我不想在字符串周围使用 "" 因为它需要被评估并且会影响性​​能......

最佳答案

for(var i = 0; i < al; i++) {
    setTimeout(function() {
        this.scrollAd(this.ads[i]);
    }.apply(this), this.timeDelay * 1000);
}

apply 不绑定(bind)一个函数,它调用它。所以你直接执行滚动,然后将它的返回值(undefined)传给setTimeout,这是无效的。

您可能打算在 this 和循环变量(它必须被关闭,否则每次超时都将是相同的循环后值)上使用这样的闭包:

for(var i = 0; i < al; i++) {
    setTimeout(function(that, j) {
        return function() {
            that.scrollAd(that.ads[j]);
        };
    }(this, i), this.timeDelay * 1000);
}

但是您可能更喜欢使用新的 ECMAScript 第五版函数绑定(bind)功能,它具有更紧凑的语法:

for (var i= 0; i<al; i++)
    setTimeout(this.scrollAd.bind(this, this.ads[i]), this.timeDelay*1000);

(在 this answer 的底部有一个 function.bind 的实现,适用于 native 没有它的浏览器。)

关于javascript - 更改 setTimeout 上的匿名函数的范围会导致奇怪的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1728563/

相关文章:

java - 最小化 do ... while 循环中变量的范围 [Java] - 错误 : Symbol cannot be found

javascript - 获取数据 promise angularJS

javascript - 坚持试图让 JS 传播带有图像的 HTML div

javascript - python对象和json对象有什么区别?

javascript - JS – 三元运算符,以避免条件中的过度链接。是否可以?

javascript - 为什么 angularjs 作用域允许在初始化之前访问变量

c++ - 在 MPI、C++ 上分配单个堆栈数组

javascript - 从 ES6 中的函数表达式访问类作用域

javascript - Nativescript 和 ListView,项目未定义

javascript - 为什么我无法在 Google Chrome 中返回 cookie?