3

我是一名 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);
});
4

5 回答 5

1

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

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

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

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

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

于 2012-10-06T09:18:50.557 回答
1

好吧,首先:

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

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

使用参数在(即“认为”它属于对象的函数)的上下文中 调用函数 fwindowwindowparams

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

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

(function(param){...})("Hello world");
于 2012-10-06T09:18:53.740 回答
1

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

tempfn = function(name, fn) { /* body */ };
window[name] = tempfn(name, fn);
于 2012-10-06T09:19:38.123 回答
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);
   });

And, in the loop

 window[name] = fn2.apply(name, fn);         
于 2012-10-06T09:20:01.493 回答
1

The problem you are trying to circumvent here is referencing name and fn in your loop afterwards. If you just did window[name] = function () { alert(name); } all your assigned functions would always use the value that name was last set to, not what it was when that particular function was defined in your loop. To get around this you create a function that is called immediately with the correct values and that way protects them in a new closure. You can read more about it in this SO-question: JavaScript closure inside loops – simple practical example

于 2012-10-06T09:20:58.200 回答