您的位置:首页 > 其它

闭包

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.闭包会在函数外部改变复函数内部变量的值,所以,如果把复函数当做对象使用,把闭包当做它的共有方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变函数内部变量的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: