济南标梵web前端开发中闭包代码示例分享

 

 闭包,获取一个局部作用域里变量的访问权限,涉及到作用域栈、执行上下文、垃圾回收机制、内存驻留以及性能问题,闭包切断作用域栈产生的垃圾回收事件,实现变量的内存驻留。主要应用场景在需要累积效应、重复循环事件、前后事件相关等。因而,为避免产生严重的性能问题,在完成事件任务后要把闭包置为null,释放内存。

这里介绍JS中作用域栈的特性,即先进后出,全局作用域位于栈底,局部作用域按照编译、执行顺序依次入栈,执行完毕依次出栈,对变量进行垃圾回收,释放内存。了解此特性,利用全局作用域始终位于栈底,并且总是最后完成垃圾回收,只要在局部作用域中装载具有全局效应的作用域,阻断垃圾回收,就完成了闭包的设计。

 

示例1:

  1. function foo(x) { 

  2.     var tmp = 3; 

  3.     return function (y) { 

  4.         console.log(x + y + tmp); 

  5.         x.memb = x.memb ? x.memb + 1 : 1; 

  6.         console.log(x.memb); 

  7.     } 

  8. var age = new Number(2); 

  9. var bar = foo(age); // bar 现在是一个引用了age的闭包 

  10. bar(10);

 

示例2:

  1. function foo(x) { 

  2.     var temp = 3; 

  3.     return function (y) { 

  4.         console.log(x + y + (++temp)); 

  5.     } 

  6. var bar = foo(2); 

  7. bar(10);

 

示例3:

  1. function badClosureExample() { 

  2.     var as = document.querySelectorAll('a'); 

  3.     for (var i = 0; i < 4; i++) { 

  4.         as[i].onclick = new popNum(i); 

  5.         function popNum(oNum) { 

  6.             return function () { 

  7.                 alert('单击第' + oNum + '个'); 

  8.             } 

  9.         } 

  10.     } 

  11. badClosureExample();

 

示例4:

  1.  function badClosureExample() { 

  2.     var as = document.querySelectorAll('a'); 

  3.     for (var i = 0; i < 4; i++) { 

  4.         (function (i) { 

  5.             as[i].onclick = function () { 

  6.                 alert('单击第' + i + '个'); 

  7.             } 

  8.         })(i); 

  9.     } 

  10. badClosureExample();

 

1、将变量 i 保存给在每个段落对象(p)上

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         pAry[i].i = i; 

  5.         pAry[i].onclick = function () { 

  6.             alert(this.i); 

  7.         } 

  8.     } 

  9. init();

 

 

2、将变量 i 保存在匿名函数自身

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         (pAry[i].onclick = function () { 

  5.             alert(arguments.callee.i); 

  6.         }).i = i; 

  7.     } 

  8. init();

 

3、加一层闭包,i 以函数参数形式传递给内层函数

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         (function (i) { 

  5.             pAry[i].onclick = function () { 

  6.                 alert(i); 

  7.             } 

  8.         })(i);//调用时参数 

  9.     } 

  10. init();

 

4、加一层闭包,i 以局部变量形式传递给内层函数

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         (function () { 

  5.             var index = i;//调用时局部变量 

  6.             pAry[i].onclick = function () { 

  7.                 alert(index); 

  8.             } 

  9.         })(); 

  10.     } 

  11. init();

 

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         pAry[i].onclick = function (i) { 

  5.             return function () { //返回一个函数 

  6.                 alert(i); 

  7.             } 

  8.         }(i) 

  9.     } 

  10. init();

 

6、用Function实现,实际上每产生一个函数实例就会产生一个闭包

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         pAry[i].onclick = new Function("alert(" + i + ")"); 

  5.         //new一次就产生一个函数实例 

  6.     } 

  7. init();

 

7、用Function实现,注意与6的区别

  1. function init() { 

  2.     var pAry = document.getElementsByTagName("p"); 

  3.     for (var i = 0; i < pAry.length; i++) { 

  4.         pAry[i].onclick =Function("alert(" + i + ")"); 

  5.     } 

  6. init();

  7.  

本文编辑:标梵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值