zoukankan      html  css  js  c++  java
  • js闭包

    我们先来看一个简单的例子:

    1 function one(){
    2   var a=30;
    3   return function(){
    4      return a;
    6 } 7 } 8 var func=one(); 9 func();

    显然,最后的结果为:30;

    在上面的例子中,我们执行了 func=one();之后,返回的是return的匿名函数,该匿名函数任然能够访问外部的局部变量 a,这种情况就是我们所说的闭包。在一般的函数中,函数在执行完成之后,就会释放掉该函数中的局部变量,但是闭包不会,闭包会使该局部变量一直保存在内存中。

    在一些专业的文献中对闭包的解释是:闭包是指函数或函数的引用,与一个引用环境绑定在一起,这个引用环境是一个存储该函数每个非局部变量的表。

    从简单来讲,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

    闭包的作用:一是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    但是,我们有时会遇到这样的情况:比如说,我们想要这个函数返回所有的 i 的值:

    1 function one(){
    2   var a = new Array();
    3   for(var i=0;i<5;i++){
    4     a[i] = function(){
    5       return i;
    6     };
    7   }
    8   return a;
    9 }

     表面上看,每个函数都应该返回自己的索引值,但实际上,每个函数都返回5.因为每个函数的作用域链中都保存着 one() 函数的活动对象,他们都引用的是当 one() 函数返回后的 i 的值,即为 5 。这时,我们如果想要达到预期的效果,我们可以通过穿件另一个匿名函数强制让闭包行为符合预期:

     1 function one(){
     2   var a = new Array();
     3   for(var i=0;i<5;i++){
     4     a[i] = function(num){
     5       return function(){
     6         return num;
     7       };
     8     }(i);
     9   }
    10   return a;
    11 } 

    在修改过后的代码中,我们重新定义了一个匿名函数,而且是立即执行的匿名函数,给这个函数传入了一个参数,即每次循环的 i 的值,这时最内层返回的 num 就是每次 i 的循环的值,可以达到我们的预期。

    总结:从上面所说到的闭包的作用“可以使变量始终保持在内存中“中可以得到,有时在比较复杂的作用域环境中,在函数被调用之后,任然无法知道后面在何时还会再用到这些环境,所以会导致空间浪费,内存泄漏,性能消耗等坏处。所以我们要合理的使用闭包。

  • 相关阅读:
    1-直播转点播
    3-美团 HTTP 服务治理实践
    3-SSDB 高性能NoSQL数据库, 用于替代 Redis.
    配置kubectl在Mac(本地)远程连接Kubernetes集群
    4-rocketmq 发送时异常:system busy 和 broker busy 解决方案
    3-RocketMQ 简单梳理 及 集群部署笔记
    2-Rocketmq产品架构(参考阿里云)
    1-RocketMq 学习 中文文档(一)
    tar命令参数详解
    Ubuntu 安装 .bundle 文件
  • 原文地址:https://www.cnblogs.com/Pvision/p/7262753.html
Copyright © 2011-2022 走看看