接触到闭包,主要还是因为看到var与let的区别的时候在想,那么在ES6之前的话,是怎样存在块级作用域的。由于,在ES5,只有function有作用域,var没有块级作用域,因此我们可以使用闭包。
<body> <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <script> var btns = document.getElementsByTagName('button'); for (var i=0; i<btns.length; i++) { (function (i) { // 0 btns[i].addEventListener('click', function () { console.log('第' + i + '个按钮被点击'); }) }) (i) }
上述for循环的例子,是一个很好说明闭包的例子,所运行出来的结果如下:
其运行出来的结果与使用let命令出来的结果是一样的
<body> <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <script> const btns = document.getElementsByTagName('button') for (let i = 0; i < btns.length; i++) { btns[i].addEventListener('click', function () { console.log('第' + i + '个按钮被点击'); }) } </script> </body>
在学习闭包问题时,有看到一道蛮有意思的闭包题,记录下,方便之后重温。
function fun(n,o){ console.log(o) return{fun:function(m){ return fun(m,n);} }; } var a=fun(0); a.fun(1); a.fun(2); a.fun(3) ; var b=fun(0).fun(1).fun(2).fun(3); var c=fun(0),fun(1); c.fun(2), c.fun(3);
一个个看,于a中,显然代入n=0,那么打印出来的结果为undefined,因此var a打印出来为undefined,a.fun(1),则此时,可知m=1,n=0。也就意味着,n=1,o=0,因此a.fun(1)的结果为0。a.fun(2),可得知m=2,n=0,也就意味着,n=2,o=0,因此a.fun(2)的结果也为0,a.fun(3)的结果根据上述可类推出,亦为0。
于b而言的话,我们可以分着看
fun(0) => {fun:function(m){ return fun(m,0)}} // undefined fun(0).fun(1) => fun(1,0) => {fun:function(m){return fun(m,1)}} // 0 fun(0).fun(1).fun(2) => fun(2,1) => {fun:function(m){return fun(m,2)}} // 1 un(0).fun(1).fun(2).fun(3) = fun(3,2) //2
因此输出结果为 undefined,0,1,2
于c的话,c = {fun:function(m){return fun(m,1)}}。因此c.fun(2)和c.fun(3)调用的结果都是会打印1,所以输出结果为:undefined,0,1,1