什么是闭包?
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
通俗的讲:就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。
javascript语言的特别之处就在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。所以在要获得函数内部变量时,只能在函数内部再定义一个函数。
所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
或者说两种情况:函数作为返回值,函数作为参数传递。
下面来三个最常见的闭包代码:
1.闭包计数
var add = function(){ var counter = 0; return function(){ return(++counter); } }; var a = add() var b = add() console.log(a()) // 1 console.log(a()) // 2 console.log(b()) // 1
2.闭包事件
<p>文字1</p> <a href="javascript:void(0)">red</a> <a href="javascript:void(0)">green</a> <a href="javascript:void(0)">blue</a>
$('a').click(function(){ changeColor($(this).html())() }) function changeColor(color){ return function(){ $('p').css('color',color) } }
3.常见闭包陷阱
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]()); }
这段代码输出的是10个10 ,因为return i 是在函数执行时才去取i的值的,这时候循环中的i已经变为了10
两种方法可以把输出结果改为0到9
一种是用将var i 换位let i
function createFunctions(){ var result = new Array(); for (let i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]()); }
另一种是用立即执行函数,
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = (function(){ return i; })(); } return result; } var funcs = createFunctions(); for (var i=0; i < funcs.length; i++){ console.log(funcs[i]); }