闭包
把重要的数据包起来,不能直接修改,闭包让数据更安全
主要靠函数内部局部变量的作用域 特征实现 ,改变局部变量的值
闭包的特征
- 外函数嵌套里函数
- 外层函数创建局部变量
- 里层函数使用外层函数的变量
- 里层函数能够在其他地方触发(通过return里层函数)
闭包的优劣
- 闭包的优势(价值):修改局部变量的值,使数据更安全
- 闭包的缺点:由于局部变量可修改,所以需要一直占用内存,不会被垃圾回收清理。过多的使用闭包会导致内存压力增加,页面变卡。
案例
这个案例是关于闭包的this的解析:
1.外层函数被对象object所调用,故外层函数的this为object
2.而内层函数是被return出去以后在全局的区域下被调用,
又没有引用上一层的this,故其this为window
<script>
// /* 全局变量 name */
// var name = "The Window";
// /* 对象 object */
// var object = {
// name: "My Object",
// getNameFunc: function () {
// // console.log(this); // object
// return function () {
// console.log(this === window); // true
// console.log(this); // window
// return this.name;
// };
// }
// };
//
// /* 调用了对象的方法 */
// var res = object.getNameFunc();
// var liFnRes = res();
// console.log(liFnRes); // "The Window"
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
var that = this; // 这一步 object
return function () {
return that.name; // 用的是上一个作用域的局部变量
};
}
};
var res = object.getNameFunc();
var LifnRes = res();
console.log(LifnRes); // "My Object"
</script>
这个案例是关于闭包的运用 (投票模块)
1.这里在js里面封装了一个闭包函数,其外层函数有一个变量为count(即投票的初始 值)
2. 里函数的作用是,每次调用时把count++,并把count放到按钮上面
3.给每个按钮注册点击事件,其事件的回调函数绑定为调用外层函数返回的结果(即带有一个外层变量count的里层函数)
4.每个按钮的点击事件所绑定的里层函数其实是不一样的(return的特点),故每一个count都是相互独立的,所以可以有点击只给自己加点击数的效果
<ul>
<li><img alt="" src="img/liudehua.jpg"/><input type="button" value="投票(0)"/></li>
<li><img alt="" src="img/zhourunfa.jpg"/><input type="button" value="投票(0)"/></li>
<li><img alt="" src="img/liudehua.jpg"/><input type="button" value="投票(0)"/></li>
<li><img alt="" src="img/zhourunfa.jpg"/><input type="button" value="投票(0)"/></li>
</ul>
</body>
</html>
<script>
/* 闭包基本结构 */
function wai() {
var count = 0;
/* 里层函数作为外层函数调用后的返回值 */
return function () {
count++;
console.log(count);
// console.log(this);
/* 里函数赋值给了 按钮点击事件,所以 this 指向当前点击的按钮 */
this.value = '投票(' + count + ')';
}
}
/* 查找所有按钮元素 */
var btns = document.querySelectorAll('input');
/* for 循环给所有按钮添加点击事件 */
for (var i = 0; i < btns.length; i++) {
/* 把外层函数执行后的<返回值> 赋值给 点击事件 */
btns[i].onclick = wai();
}
</script>