0

仅仅为了保留上下文而制作 jQuery 闭包是不好的做法吗?

例子:

{
    testFunction: function() {
        //Instantiate variables etc...

        for (var i = 0; i < columns.length; i++) {
            for (var j = 0; j < columns[i].length; j++) {
                // create a closure so the .then callback has the correct value for x
                var func = function() {
                    var x = new testObject(columns[i][j].Id);

                    // find method returns a jQuery promise
                    x.find().then(function() {
                        // use x for some logic here
                    });
                };
                func();
            }
       }
   }
}

在这种情况下,需要闭包,以便 jQuery 承诺的函数具有 x 的上下文。否则,x 变量在循环的下一次迭代后被更改。jQuery Promise 对象获取循环最后一次迭代中 x 的值。

我在这里寻找最佳实践,只是想知道如何保持代码简单、可读和高效。

请注意任何与闭包/不使用闭包相关的性能问题。参考是赞赏。

4

4 回答 4

3

使用闭包绝对是一个好习惯,但您可以稍微简化一下:

  1. 将对象直接传递给您的闭包。
  2. 使用IIFE而不是命名函数声明。
for (var i = 0; i < columns.length; i++) {
    for (var j = 0; j < columns[i].length; j++) {
        (function(x) {
            x.find().then(function() {
                // use x for some logic here
            });
        }( new testObject(columns[i][j].Id) ));
    }
}

注意:您可以使用 jQuery 的方法稍微简化此代码$.each(),但使用常规for循环更快

于 2013-09-03T19:33:38.550 回答
2

与循环相比,jQuery(或 ES5)迭代器通常会产生更简洁的代码。考虑:

$.each(columns, function() {
    $.each(this, function() {
        var x = new testObject(this.Id);
        x.find().then(function() {
            // stuff
        });
    });
});

请注意,这里不会出现范围问题,因为您会在每次迭代中自动获得一个新范围。为了解决性能问题,迭代器循环慢,但在事件驱动的世界中,您几乎不需要担心这一点。

于 2013-09-03T19:40:08.547 回答
1

不幸的是,没有更好的方法来解决这个问题。但是,您错过了通过 i 和 j:

for (var i = 0; i < columns.length; i++) {
    for (var j = 0; j < columns[i].length; j++) {
        // create a closure so the .then callback has the correct value for x
        var func = function(i, j) {
            var x = new testObject(columns[i][j].Id);
            // find method returns a jQuery promise
            x.find().then(function() {
                // use x for some logic here
            });
        };
        func(i, j);
    }
}
于 2013-09-03T19:35:49.290 回答
0

没关系,这实际上是创建上下文的唯一方法。

不幸的是,由于某些原因,我真的不明白有 Javascript 引擎将您可以创建的嵌套函数的数量限制在非常低的数字,所以只在真正需要时尝试使用它们(例如,我发现我非常强大的 Galaxy S4 Android 只能处理 18 个嵌套级别)。

对于手写代码,这通常不是问题,但对于生成的 javascript 代码,很容易克服那些难以言喻的限制。

于 2013-09-03T19:39:52.287 回答