Extra parentheses on function
Possible Duplicate:
What do parentheses surrounding a JavaScript object/function/class declaration mean?
What does this “(function(){});”, a function inside brackets, mean in javascript?
A Javascript function
我遇到类似这样的标记:
1 2 3 4 5 | var something = (function(){ //do stuff return stuff; })() document.ondblclick = function(e) { alert(something(e)) }; |
我不明白
你能解释一下写这样的差异吗?
1 2 3 4 | var something = function(){ //do stuff return stuff; }; |
谢谢!
如果你把冗余的parens遗漏掉,可能会更容易理解,因为它们没有用处:
1 2 3 4 5 6 7 8 9 10 11 12 13 | var something = function() { return 3; } // <-- a function. (); // now invoke it and the result is 3 (because the return value is 3) assigned to variable called something console.log(something) //3 because the function returned 3 var something = function() { return 3; }; // a function is assigned to a variable called something console.log(something) //logs the function body because it was assigned to a function console.log(something()) //invoke the function assigned to something, resulting in 3 being logged to the console because that's what the function returns |
它后面的括号将立即执行函数表达式,从而产生函数的返回值(在这里:
当
关于它的作用,请阅读所有评论和其他答案。他们是绝对正确的。
你为什么要用它?使用闭包时,您经常会发现这种模式。以下代码片段的目的是向10个不同的DOM元素添加一个事件处理程序,每个元素应该警告它的ID属性(例如"你点击了3")。您应该知道,如果这是您的实际意图,那么有一种更简单的方法可以做到这一点,但出于学术原因,让我们坚持这个实现。
1 2 3 4 5 6 7 8 9 10 | var unorderedList = $("ul" ); for (var i = 0; i < 10; i++) { $("<li />", { id: i, text:"Link" + i, click: function() { console.log("You've clicked" + i); } }).appendTo( unorderedList ); } |
上述代码的输出可能不是您首先预期的。每个点击处理程序的结果都是"你点击了9",因为触发事件处理程序时i的值是"9"。开发人员真正想要的是在定义事件处理程序的时间点显示i的值。
为了解决上述错误,我们可以引入一个闭包。
1 2 3 4 5 6 7 8 9 10 11 12 13 | var unorderedList = $("ul" ), i; for (i = 0; i < 10; i++) { $("<li />", { id: i, text:"Link" + i, click: function(index) { return function() { console.log("You've clicked" + index); } }(i) }).appendTo( unorderedList ); } |
您可以从jsFiddle执行和修改上面的代码。
修复上述代码的一种方法是利用自执行匿名函数。这是一个奇特的术语,意味着我们将创建一个无名函数,然后立即调用它。该技术的价值在于变量的范围保持在函数内。因此,首先我们将在函数中包围事件处理程序内容,然后立即调用该函数并传入i的值。通过这样做,当事件处理程序被触发时,它将包含定义事件处理程序时存在的i的值。
关于闭包的进一步阅读:JavaScript闭包的用例
所有答案都很好,但我认为最简单的答案已被撇去:
1 2 3 4 | var something = (function(){ //do stuff return stuff; })() |
执行此代码后,
1 2 3 4 | var something = function(){ //do stuff return stuff; }; |
执行此代码后,
请查看JavaScript常见问题解答部分:以下是一些非常好的解释和示例
好的,你为什么要用这个:
假设我的脚本正在运行,并且有一些事情(例如,我正在循环遍历节点列表)我可能稍后需要。这就是我选择做这样的事情的原因:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | for(var i=0;i<nodesList.lenght;i++) { if (nodesList[i].id==="theOneINeed") { aClosure = (function(node,indexInNodesList)//assign here { return function() { node.style.display = 'none';//usable after the parent function returns alert(indexInNodesList+ ' is now invisible'); } })(nodesList[i],i);//pass the element and its index as arguments here break; } } i = 99999; aClosure();//no arguments, but it'll still work, and say i was 15, even though I've just //assigned another value to i, it'll alert '15 is now invisible' |
这使我能做的是防止函数参数被垃圾收集。通常,在函数返回后,其所有var和参数都是GC'd。但在这种情况下,函数返回另一个函数,该函数具有到这些参数的链接(它需要它们),因此只要
正如我在评论中所说。谷歌关闭,练习一点,它会在你身上拂晓......它们真的非常强大