闭包
2016-06-17 21:15
204 查看
一、闭包的概念
闭包与函数有着紧密的联系,它是函数的代码在运行过程中的一个动态环境,是一个运行期的,动态的概念。由于javascript中,只有函数内部的子函数才能读取局部变量,因此,可以简单把闭包理解为:定义在一个函数内部的函数。所以,在本质上,闭包就是讲函数内部和函数外部链接起来的一座桥梁。下面来看一个例子:
var name = "xiao A"; //定义一个全局变量 var obj = { name: "xiao B", //定义一个局部变量 getName: function() { return function() { return this.name; } } }; alert(obj.getName()()); //xiao A var k = obj.getName(); //用变量k来保存getName(),此时为全局作用域 alert(typeof k); // function类型 alert(k()); // xiao A 为了能访问当obj内的局部变量xiao B,将以上代码做一些修改 var name = "xiao A"; //定义一个全局变量 var obj = { name: "xiao B", //定义一个局部变量 getNmae: function() { var o =this; //用一个变量o保存this return function() { return o.name; } } }; var k = obj.getName(); //此处访问的依然是全局作用域 alert(k()); //xiao B;在执行时访问的是obj的name属性
这就是一个简单的闭包概念。
闭包就是一个函数可以访问另一个函数作用域中的变量。
如上述代码中,getName()可以访问它上级作用域中的obj.name属性。
闭包是设计独立变量的函数,换句话说,在闭包中定义的函数会记住它创建的环境,当一个函数在它所创建的环境外执行时,它就是闭包。闭包具有封闭性,起到保护变量的作用。如obj的name属性,在函数外部无法对其进行访问。
注意:
1.当调用闭包中的方法时,每次调用都会返回一个新的函数,即便传入相同的参数。function add(arr) { var sum = function() { return arr.reduce(function(x,y) { return x+y; }); } return sum; } var f1 = add([1,2,3]); //6 var f2 = add([1,2,3]); //6 f1 === f2; // false;f1 与f2的调用结果互不影响
2.闭包只能取得包含函数中任何变量的最后一个值
function arrFunc() { var arr = []; for(var i = 0;i < 10;i++) { arr[i] = function() { return i; } } return arr; }
结果返回10个10。
当arrFunc执行完后,其作用域被销毁,但它的变量对象仍保存在内存中,得以被匿名访问。这时i的值为10,想要保存在循环过程中每一个值,需要在匿名函数外部再套用一个匿名函数,在这个匿名函数中定义另一个变量,并且立即执行来保存i的值。
function arrFunc() { var arr = []; for(var i = 0;i < 10;i++) { arr[i] = fucntion(num) { return function() { return num; } }(i); } return arr; }
或者使用ES6的块级作用域let来声明变量。
二、使用闭包需注意的问题
1.闭包使得函数中的变量保存在内存中,对内存的消耗很大,所以不要滥用闭包,否则使用不当会造成网页的性能问题,在IE章还可能导致内存泄漏,应该在函数退出之前,将不使用的局部变量全部删除。2.闭包会在函数外部改变复函数内部变量的值,所以,如果把复函数当做对象使用,把闭包当做它的共有方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变函数内部变量的值。
相关文章推荐
- java学习笔记之自定义注解
- Java多线程——安全与死锁问题
- latex 不换行
- cs231学习笔记一 图像识别与KNN
- MIPI CSI-2规范(一)——概述及层级
- PYTHON-基础-时间日期处理小结
- Android中获取布局中的布局(获取子布局方法)
- 周末作业
- C++ - PAT - 1047. 编程团体赛(20)
- 机器学习(周志华版)读书笔记1
- 300 Longest Increasing Subsequence
- 补C++ 4
- linux---谈谈vfork和fork的区别及exit与return
- 专题四1005
- hdu 1021 Fibonacci Again(斐波那契数列,取余)
- BZOJ3524 [Poi2014]Couriers
- IOS中定时器NSTimer的开启与关闭
- Leetcode 62. Unique Paths
- C++补交作业二
- CountDownLatchDemo