首页 > 代码库 > js 中的闭包
js 中的闭包
闭包:闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见方式是 在一个函数内部创建另一个函数
(从定义上讲 js 中所有的函数都是闭包)
function a(){ var i=0; function b(){ alert(++i); } return b; } var c=a(); c();
以上代码的特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
闭包就是函数或代码块执行完后不回收a中占用的资源,因为a的内部函数的执行需要依赖a中的变量
PS:全局环境的变量对象始终存在,像函数中的局部环境变量,则只在函数执行的过程中存在
作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。
PS: 由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过渡使用闭包可能会导致内存占用过多
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的用处:
a.读取函数内部的变量。
b.让这些变量的值始终保持在内存中。
使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,
否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,
把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),
这时一定要小心,不要随便改变父函数内部变量的值。
闭包容易造成的问题:
function a(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(num){ return function(){ return num; }; }(i); //若此处不传入 i值 运行代码后 获取的值 都是 10 } return result; }
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"The Window"(在非严格模式下)
object.getNameFunc() 执行后 返回的是一个函数 后面的括号又运行了该函数 相当于该函数是在全局环境中运行的。
在全局环境中this 默认指向的是window对象
所以函数里面的this.name 就是全局的变量name
解决办法:
我们知道,闭包的一个作用就是读取函数内部的变量。
如果要获取本来的对象 可以将本来的this 保存在另一个自定义的变量中 然后将该变量传入返回的函数里面。
这样该变量就会一直保存在内存中 不会被销毁
js 中的闭包