闭包是指能够引用外部函数中的局部变量的函数,并导致外部函数调用后函数对象与局部变量无法及时销毁。函数是JavaScript中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。
var Foo = function() { var name = 'staven'; this.getName = function() { return name; }; }; var foo = new Foo(); console.log(foo.name); //undefined console.log(foo.getName()); //staven### 闭包中的循环 作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); //10次输出10 }, 1000); }为了正确的获得循环序号,最好使用自执行匿名函数。
for(var i = 0; i < 10; i++) { (function(e) { setTimeout(function() { console.log(e); }, 1000); })(i); }匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window(在通过 call()或 apply()改变函数执行环境的情况下, this 就会指向其他对象)。
var name = '全局'; var obj = { name: '局部', getName: function(){ var that = this; return function(){ return that.name; } } }; console.log(obj.getName()()); //局部把外部作用域中的 this 对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。
var name = "全局"; var obj = { name: "局部", getName: function() { var that = this; return function() { return that.name; }; } }; console.log(obj.getName()()); //"局部"只要我们临时需要一些变量,都可以使用块级作用域(私有作用域)。当匿名函数执行完毕,其作用域链立即销毁,从而可以减少闭包占用资源问题。
(function($, window, document, undefined){ var name = "staven"; $.fn.getName = function(){ }; })(jQuery, window, document);缓存数据、柯里化
由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多,建议只在绝对必要时再考虑使用闭包。