一个JS闭包查询

时间:2012-10-06 09:10:37

标签: javascript

我是一名C ++(Qt)开发人员,对JS有所了解。我无法理解以下代码的一部分。你能帮帮我吗?

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];

        if (typeof fn === 'function') {
    // **Not able to understand below code.**
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    fn.apply(this, arguments);

                }
            })(name, fn);
    // **In above code I understood everything else except this last line. 
    // Why whole function is in circular bracket? Why it ends with (name, fn);
    // What is the meaning of this?
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name);
});

5 个答案:

答案 0 :(得分:1)

自执行匿名函数是解决循环中闭包问题的常用方法。

所以它实际上是一个匿名函数,它使用传递的参数立即声明和执行。

实际上name参数在那里没用,因为它没有被使用,但是如果你没有使用 - 那么只有最后一个fn参数将作为参考传递。

问题的演示:http://jsfiddle.net/zerkms/nfjtn/

解决方案(使用自动执行的匿名函数):http://jsfiddle.net/zerkms/nfjtn/1/

答案 1 :(得分:1)

嗯,首先:

(function f(param) { alert(param); })("Hello world"); 定义函数并立即执行它。

function f(param) { alert("This: = " + this + ". Param=" + param); }
f.apply(window, "Hello world");

使用参数window <在 window的上下文中调用函数f (即函数'认为'它属于params对象) / p>

function(param)返回对匿名函数的引用。那就是:

var f = function(param) {...}; f("Hello world");类似于:

(function(param){...})("Hello world");

答案 2 :(得分:1)

括号中的表达式(您称之为“圆括号”)是一个匿名函数。 (name, fn)在它的末尾意味着应该使用这些参数调用函数,并将返回值赋给window[name]。它大致相当于:

tempfn = function(name, fn) { /* body */ };
window[name] = tempfn(name, fn);

答案 3 :(得分:1)

通常在C中你会有定义(也许是声明)

int anon(string name, void* function) {
}

以及对函数的调用

anon(name, function);

圆括号内的部分是匿名函数的声明;使用(name, fn)参数立即调用。

将其视为(注意:JS可能有点生疏,因此可能会出现语法错误)

 var fn2 = (function(name, fn) {
    var args = arguments;
    return function() {
      withFn.apply(this, args);
      fn.apply(this, arguments);
   });

并且,在循环中

 window[name] = fn2.apply(name, fn);         

答案 4 :(得分:1)

您尝试绕过的问题是在您的循环中引用namefn。如果您刚刚执行window[name] = function () { alert(name); },则所有指定的函数将始终使用name上次设置的值,而不是在循环中定义该特定函数时的值。为了解决这个问题,你需要创建一个使用正确值立即调用的函数,这样可以在新的闭包中保护它们。您可以在此SO问题中详细了解它:JavaScript closure inside loops – simple practical example