多语言展示
当前在线:821今日阅读:61今日分享:18

javascript 闭包Closure理解

javascript 闭包Closure:1、是这样一种手段:通过它,内部函数在其父函数结束后依然能过够引用其外围函数(outer enclosing function)中的变量。2、有权访问另一个函数作用域的变量的函数。3、官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包产生: 当函数可以记住并访问所在的上下文时,就产生了闭包。作用:1、阻止GC回收函数作用域相关变量;2、读取修改父函数上下文内部的变量;3、父函数内部和子函数外部连接起来的一座桥梁;4、结合自执行匿名函数遮蔽全局变量。实现方式:1、定义父函数内部自由变量;2、创建并且返回函数,此函数会'捕获'父函数上下文变量绑定(除了this和arguments)。闭包的三个事实:1、javascript允许你引用当前函数以外定义的变量;2、即使外部函数已经返回,当前函数任然可以引用在外部函数所定义的变量;3、闭包可以更新外部变量的值。闭包的应用:1、在定时器,事件监听器、ajax请求、跨窗口通信,web workers或者其他的异步(或同步)任务中,只要使用了回调函数,实际上就是在使用闭包。2、模块暴露公共API定义3、循环和闭包:延时输出循环变量,绑定对象引用4、函数柯里化
方法/步骤
1

// 示例:两个利用闭包来增加代码清晰度的例子// 找到ID为main的元素var objEle = document.getElementById('main');// 更改边框样式objEle.style.border = '1px solid red';// 初始化回调函数,该函数会在1秒之后被调用setTimeout(function() {// 隐藏对象objEle.display = 'none';}, 1000);// 一个通用函数,显示一条延迟的警告信息function delayeAlert(msg, time) {// 初始化内部的回调函数setTimeout(function() {// 使用从外部函数传入的msgconsole.log(msg);}, time);}// 调用函数delayeAlert并传入两个参数delayeAlert('Welconme', 2000);

2

// 示例:使用闭包技术的函数柯里化// 定义一个函数,该函数生成一个新的加法函数function addGenerator(num) {// 返回一个将两个数字相加的简单函数,其中第一个参数重该函数生成器中获取return function(toAdd) {return num + toAdd;};}// addFive中包含了一个函数,该函数接受一个参数,然后将该参数与5相加并且返回计算结果var addFive = addGenerator(5);// 在这里可以看到,给函数addFive传入一个值为4的参数时,得到的结果是9console.log(addFive(4) === 9);

3

// 示例:使用匿名函数隐藏全局变量// 创建一个匿名函数作为包装器来使用(function() {// 这些变量通常都是作为全局变量var msg = 'Thanks for visiting!';// 将一个新函数绑定到全局对象window.onload = function() {// 使用隐藏变量console.log(msg);};// 结束匿名函数定义并执行})();

4

// 示例:使用匿名函数来生成创建多个闭包函数所需要的作用域// ID为main元素var objElement = document.getElementById('main');// 要绑定的数组var onItems = ['click', 'keypress'];// 迭代数组中的每一项for (var i = 0; i < onItems.length; i++) {// 利用自执行的匿名函数生成作用域(function(j) {// 记住这一作用域中的值// 在该作用域的每个item和j的值都是唯一的,不依赖父上下文中所创建的变量var item = items[j];// 为元素绑定事件函数objElement['on' + item] = function() {// item指向的是处于for循环上下文中的父变量console.log('Thanks for your ' + item);}})(i);}

注意事项

javascript滥用闭包造成内存泄漏

推荐信息