关于闭包的解读

变量作用域

要理解闭包,首先要理解变量的作用域,在JavaScript中,变量的作用域分为两种,全局作用域以及局部作用域。JavaScript语言的特别之处就在于,函数内部可以访问函数外部的全局变量,但是函数外部无法读取函数内部的局部变量。

如何从函数外部读取函数内部的局部变量?

出于种种原因,我们有时候需要获取到函数内部的局部变量。但是,上面已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。那就是在函数内部,再定义一个函数。

function a(){
    var i=0;
    function b(){
        alert(i);
    }
}

在上面的代码中,函数b是包含在函数a中的,那么函数a中的所有局部变量,在函数b中都是可访问的。相反,函数b中定义的局部变量,在函数a中并不可见。这就是JavaScript中的作用域链。
子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然b可以读取a中的局部变量,那么只要把b作为返回值,我们不就可以在a外部读取它的内部变量了吗!像下面这样

function a(){
    var i=0;
    return function b(){
        alert(i);
    }
}
var c=a();
c();  //会弹出0

闭包的概念

在上面的代码中,就形成了闭包,闭包是指有权访问另外一个函数作用域中的变量的函数,这个概念告诉我们两点:

  • 闭包其实是一个函数
  • 这个函数可以访问其他函数作用域中的变量

闭包的应用场景

  • 采用函数引用方式的setTimeout调用
function fun(num){
    var age=num;
    return function(){
        console.log(age);
    }
}
var getAge=fun(200);
setTimeout(getAge,1000);
  • 给对象设置私有变量,并且利用特权去访问私有变量
function Fun(){
  var name = 'tom';
  this.getName = function (){
    return name;
  }
}
var fun = new Fun(); 
console.log(fun.name);//输出undefined,在外部无法直接访问name
console.log(fun.getName());//可以通过特定方法去访问
  • 封装相关功能集

一个内联执行的函数表达式返回了内部函数对象的一个引用。并且分配了一个全局变量,让它可以被作为一个全局函数来调用。而缓冲数组作为一个局部变量被定义在外部函数表达式中。它没有被扩展到全局命名空间中,并且无论函数什么时候使用它都不需要被再次创建。

var getImgInPositionedDivHtml = (function () {
   var buffAr = [
     '<div id="',
     '',   //index 1, DIV ID attribute  
     '" style="position:absolute;top:',
     '',   //index 3, DIV top position  
     'px;left:',
     '',   //index 5, DIV left position  
     'px;width:',
     '',   //index 7, DIV width  
     'px;height:',
     '',   //index 9, DIV height  
     'px;overflow:hidden;\"><img src=\"',
     '',   //index 11, IMG URL  
     '\" width=\"',
     '',   //index 13, IMG width  
     '\" height=\"',
     '',   //index 15, IMG height  
     '\" alt=\"',
     '',   //index 17, IMG alt text  
     '\"><\/div>'
   ];
   return (function (url, id, width, height, top, left, altText) {
     buffAr[1] = id;
     buffAr[3] = top;
     buffAr[5] = left;
     buffAr[13] = (buffAr[7] = width);
     buffAr[15] = (buffAr[9] = height);
     buffAr[11] = url;
     buffAr[17] = altText;
     return buffAr.join('');
   });
 })();

闭包所引发的问题

  • 内存泄漏

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

  • this的问题

this对象是在运行时基于函数的执行环境绑定的,在全局函数中,this等于window,而当函数作为某个对象的方法调用时,this等于那个对象。不过匿名函数的执行环境具有全局性,因此其this对象通常指向window。但有时候,由于编写闭包的方式不同,这一点可能不会那么明显。也就是说使用闭包,有可能会意外改变this的值。所以在实际场景中,我们一定要谨慎使用闭包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值