js闭包

闭包,一直是一个比较让人晦涩难懂的,面试中还经常会被问到,那么到底什么是闭包呢?我们来看一段代码

function fn(){
    var a = 1;
}
console.log(a);    // a is not defined

放到浏览器中执行,发现报错了,原因我想大家也都清楚,由于js中作用域的原因,函数外部是无法直接获取函数内部的一些局部变量的,注意我说的是局部变量,如果是全局变量是可以访问的,如下代码

function fn(){
    a = 1;
}
fn();
console.log(a);        //1

言归正传,那么如果真的有需求需要获取函数中的局部变量,这时候怎么办?那就要用到闭包了

function fn(){
    var a = 1;
    function fn2(){
        alert(a);
    }
    return fn2;
}
var f1 = fn();
f1();        //1

如上就是一个闭包,可以看到我们已经访问到了fn中的局部变量,当然,不用闭包,用其他的方法也能访问,我们改一下代码

function fn(){
    var a = 1;
    return a;
}
var f1 = fn();
console.log(f1);        //1

同样做到了,那么闭包到底有什么用呢?网上查了一些资料也是无解,我就以我的理解来说吧

首先,闭包就是函数嵌套函数,相对于直接return一个变量,闭包可以在被嵌套函数内部做一下逻辑然后再返回,功能更强大

我们再来看一个例子感受一下闭包的好处

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<button>Button0</button>
<button>Button1</button>
<button>Button2</button>
<button>Button3</button>
<button>Button4</button>
</body>
<script>
var btns = document.getElementsByTagName('button');
for(var i = 0, len = btns.length; i < len; i++) {
(function(i) {
btns[i].onclick = function() {
alert(i);
}
})(i)
}
</script>
</html>

点击按钮我们就可以得到对应的索引,这用普通的for循环遍历,添加事件是做不到的,闭包为何能做到呢?

这是因为每次循环的i值都被封闭起来,这样在函数执行时,会查找定义时的作用域链,这个作用域链里的i值是在每次循环中都被保留的,因此点击不同的button会alert出来不同的i。

闭包有一个很重要的特点,即是优点也是缺点,那就是变量始终保存在内存中,不会被垃圾回收机制所回收,这也就意味着会造成内存泄漏。所以不能滥用闭包,否则会造成网页的性能问题,解决方法是,在退出函数之前,将不使用的局部变量全部删除。

posted @ 2017-11-28 19:31  阿弥陀佛么么哒!  阅读(191)  评论(0编辑  收藏  举报