C#的lambda表达式也有闭包,但C#社区或书籍很少讨论。与C#世界相比,我看到更多的JavaScript人和书籍谈论其闭包。这是为什么?
C#的lambda表达式也有闭包,但C#社区或书籍很少讨论。与C#世界相比,我看到更多的JavaScript人和书籍谈论其闭包。这是为什么?
Answers:
因为javascript不具有名称空间之类的功能,所以您可以很容易地将各种全局对象弄乱。
因此,重要的是能够在其自己的执行环境中隔离一些代码。封闭是完美的。
在像C#这样的语言中,闭包的使用是没有意义的,在C#中,您具有名称空间,类等来隔离代码,而不是将所有内容置于全局范围内。
javascript代码的一种非常常见的做法是这样写:
(function(){
// Some code
})();
如您所见,这是一个匿名函数声明,其后立即执行。因此,无法从外部访问函数中定义的所有内容,并且不会弄乱全局范围。只要某些代码可以使用该函数的执行上下文(例如在此上下文中定义的嵌套函数),就可以将其作为回调或任何其他形式传递。
JavaScript与C#是一种非常不同的语言。它不是面向对象的,而是面向原型的。这最终导致非常不同的实践。
无论如何,闭包是好的,所以即使在C#中也要使用它们!
编辑:在对stackoverflow的聊天进行了一些讨论之后,我认为必须解决这一难题。
示例代码中的函数不是闭包。但是,此功能可以定义局部变量和嵌套函数。使用这些局部变量的所有嵌套函数都是闭包。
这对于在不影响全局范围的情况下跨一组功能共享某些数据很有用。这是javascript中闭包的最常见用法。
闭包比共享这样的数据要强大得多,但是让我们现实一点吧,大多数程序员对函数式编程一无所知。在C#中,您将使用类或名称空间进行此类使用,但是JS不提供此功能。
使用闭包可以做更多的事情,而不仅仅是保护全局范围,但这就是您在JS源代码中看到的。
可能是因为JavaScript面向对象的流行实现依赖于闭包。让我们看一个简单的例子:
function counter() {
var value = 0;
this.getValue = function() { return value; }
this.increase = function() { value++; }
}
var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());
方法getValue
和increase
实际上是闭包,封装了变量value
。
因为许多使JavaScript“可承受”的库都在使用它们。
看一下JQuery,Prototype或MooTools,仅举三个流行的例子。这些库中的每一个都each
为它们的集合提供一种方法,作为迭代的首选方法,该方法使用迭代器函数。当访问外部范围中的值时,该函数将是一个闭包:
[1,2,3].each(function(item) {
console.log(item);
});
而且它还不止于此:Ajax中的回调,Ext.js中的事件处理等都具有函数,并且如果您不想使用仅被调用一次的100ed函数膨胀代码,那么闭包是可行的方法。
console.log
在外部范围中定义,因此console
“自由变量”也是。而且,为什么实际上是一个for循环(没有什么不同)是不好的做法?
主要原因是因为C#是静态类型的,并且函数只能访问单个预定的环境,这阻碍了闭包的用处。
另一方面,在JavaScript中,闭包使函数在作为对象属性被访问并成为一类对象时可以充当方法,也可以将它们注入不同的环境中,从而允许子例程在不同的上下文中运行。
我必须了解它们的一个原因是,当您遍历DOM元素(或真正的任何东西)时,您希望能够“关闭”或“封装”变量作用域。如此处发布的示例所示:https : //stackoverflow.com/questions/5606059/how-to-create-closure-in-loop-and-store-it-in-variable-for-later-execution