javascript——闭包

闭包的原理特性

闭包:是指有权访问另一个函数作用域中的变量的函数。

创建闭包的常见方式:在一个函数内部创建另一个函数

分析上面的话,划重点:闭包是一个函数,函数,函数。重要事情说三遍。然后就是它有特权,可以访问另一个函数作用域的变量。其实这个另一个函数就是外部函数。

之前一篇文章讲到了作用域和作用域链。https://blog.csdn.net/viewyu12345/article/details/79653587

来解释闭包为何有这种特殊性。当一个函数被调用的时候,我们知道会创建一个执行环境及相应的作用域链,使用arguments和其他命名参数的值来初始化函数的活动对象。作用域链的末端永远是是全局对象,开始端就是当前的活动对象。咱调用函数不就是处理数据之类的,但是处理数据就涉及到访问数据。那么这个作用域链就规定了你如何访问(从初始端往上),哪些可以访问(在作用域链中的数据才能访问到)。

一般来说,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。半路杀出个程咬金,闭包逆天了,就不同!

闭包将会包含外部函数的活动对象

function compare(propertyName) { 
 
 return function(object1, object2){ 
     var value1 = object1[propertyName]; 
     var value2 = object2[propertyName]; 
 
     if (value1 < value2){ 
         return -1; 
     } else if (value1 > value2){ 
         return 1; 
     } else { 
         return 0; 
     } 
 }; 
}

语言太苍白,还是代码比较直观点。上面这个代码内部返回的就是一个闭包。可以看到,里面还使用了外部函数的变量propertyName。之所以能够访问这个变量,其实就是上面说的,包含了外部函数的作用域。

分析一下这个匿名函数执行的时候的作用域链,就一目了然了,这里作用域链的作用必须明白。

左侧的黑色圆圈没有任何意义,只是为了形象的表达作用域这个链。便于理解吧。

这样从图中就可以知道,外部函数的作用域还是存在在匿名函数的作用域链中。即使外部函数执行完成,外部函数的作用域链销毁,但是匿名函数没有。

闭包的缺陷

内存问题

由于闭包的特殊性,会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,所以我们有必要在在不用的时候释放内存,以便垃圾回收器回收。

//创建函数
var compareNames = compare("name"); 
//调用函数
var result = compareNames({ name: "Nicholas" }, { name: "Greg" }); 
//解除对匿名函数的引用(以便释放内存)
compareNames = null;

访问变量问题

闭包只能取得包含函数中任何变量的最后一个值。

上经典的循环读取变量问题

function createFunctions(){ 
 var result = new Array(); 
 for (var i=0; i < 10; i++){ 
     result[i] = function(){ 
         return i; 
     }; 
 } 
 return result; 
}

老手看这个太简单了,但是新手会觉得result数组返回的就是返回0-10的函数 ,其实全是返回10的函数。

解决办法:

function createFunctions(){ 
 var result = new Array(); 
 for (var i=0; i < 10; i++){ 
     result[i] = function(num){ 
         return function(){ 
             return num; 
         }; 
     }(i);
 } 
 return result; 
}

稍稍改动一下返回的函数。这时候,我们每次都会传递i进去,参数我们知道其实就是副本,那么num每次都是不一样的。在这个函数里面我们又创建了一个闭包,来每次的访问这个num,因此达到我们想要的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值