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