这些闭包的例子有什么不同
What is the difference in these examples of closures?
我在每个测试用例中都有两种情况。我想了解其中的区别,并想更多地了解闭包。
测试1:
somefunction(someobj);
和
somefunction(function(){ return someobj; });
测试2
for(;;){
someoperations;
}
和
for(;;)(function(iterator){
someoperations;
})(iterator);
测试3:
var x = (function() {
return {};
})();
和
(function() {
//this = window
var x = function() {
//this = instance of x
this.something = somethingelse;
}
//making it global OR making it available outside closure.
return (this.x=x);
})();
我需要解释在每个测试用例中以第二种方式使用它的优点。
在javascript中,创建新变量作用域的唯一方法是在函数中。
是否需要新的范围将完全取决于情况。因此,您提供的一般示例不允许给出明确的答案。
为了给出更具体的内容,我们可以使用测试2,并应用这个非常常见的场景,其中someoperations
是一个异步调用,类似于setTimeout
:
for( var i=1; i<4; i++ ) setTimeout( function() { alert( i ); }, 1000 * i);
问题是,在循环中创建的每个函数(并传递给setTimeout
)都引用了相同的i
变量,而且因为它是一个setTimeout
,它是非阻塞的,所以在调用在循环中生成的任何函数之前,循环都会完整结束。
结果是,每个函数都会提醒4
,因为循环后i
的值就留在了那里。
示例:http://jsfiddle.net/Ng3rr/
另一方面,如果在设置setTimeout
的循环中调用一个函数,并将i
的值传递给该函数,则发送给setTimeout
的每个函数所引用的变量将是本地inner_i
,它引用了传递给外部调用的值。
(我称之为inner_i
以区分两者,但您也可以将内部变量命名为i
。这样做被称为变量阴影。)
for( var i=1; i<4; i++ )(function( inner_i ){
setTimeout( function() { alert( inner_i ); }, 500 * inner_i);
})( i );
现在,每个警报都显示在每次迭代期间收到的值。
正如你所看到的,这完全取决于情况。
示例:http://jsfiddle.net/Ng3rr/1/
为了与上面的例子形成对比,如果我们没有在循环中运行任何异步代码,那么外部函数就没有必要了。
此:
for( var i=1; i<4; i++ ) alert( i );
示例:http://jsfiddle.net/Ng3rr/2/
这个:
for( var i=1; i<4; i++ )(function( inner_i ){
alert( inner_i );
})( i );
示例:http://jsfiddle.net/Ng3rr/3/
将具有相同的行为,使得外部功能不必要。
因此,调用外部函数会创建一个新的变量范围。在这个新的作用域中,变量将由在该作用域中创建的任何其他嵌套函数保留。
此外,虽然在该作用域中创建的变量可以在嵌套于该作用域的函数中访问,但它们在该作用域之外是不可用的。这样可以避免使用其他变量名污染周围的作用域。
让答案不受JavaScript限制。
有几种方法可以将函数用作变量/参数,其中一种方法嵌套在另一个函数中,称为"闭包"。
你可以在这里查看"闭包"的完整描述:
http://en.wikipedia.org/wiki/Closure_%28computer_science%29
我建议对于非常长的扩展代码使用单独的函数(情况1),对于短代码使用嵌套函数(情况2)。
- 什么'这个javascript闭包的区别是什么
- 为Google闭包类定义属性的首选方式是什么
- 闭包中的本地变量从外部更改.这是一个javascript错误,或者我做错了什么
- @internal react 代码中的 JavaScript 文档标签,是 jsdoc、闭包还是其他什么
- 什么是闭包编译器
- 除了隐藏在多范式/函数式语言(如 JavaScript)中的信息之外,闭包的真正价值主张是什么?
- 将“(0)”附加到此闭包函数的目的是什么
- 将闭包编译器的类型安全性与AMD(requirejs)结合在一起的最可靠方法是什么?
- 将模块隐藏在闭包中的原因是什么
- 为什么我从两个函数中得到两个不同的结果;利用闭包似乎没有什么不同
- 在谷歌'的闭包编译器,{Element}和{HTMLElement}之间有什么区别
- 闭包的确切含义是什么
- 使用闭包编译器时,导出库方法的最佳方式是什么
- javascript中闭包到底解决了什么困难
- 这两个使用父类的函数闭包有什么区别吗?
- 是什么导致了这种行为?(闭包,引用)
- 递归闭包返回什么?
- 在Angular中,在闭包中引用服务属性/方法最合适的方式是什么?
- 闭包真正指的是什么?
- 什么工具输出这种格式?谷歌闭包编译器