js闭包_深入浅出

由浅入深的对闭包进行剖析:

先简单的对闭包做一个理解:

概念:当内部函数被保存在外部时,将会产生闭包。

简单的来个闭包的小总结,方便理解下面介绍:

  • 闭包产生是:函数内嵌套函数;
  • 闭包函数在外面被调用,访问;
  • 闭包能使外部函数访问内部函数的变量;
  • 闭包可以保持对定义时的作用域的引用,使之不被销毁,就长生不老。

在看闭包之前我们还需要理解作用域

作用域主要分为两种:全局变量和局部变量。

全局变量&局部变量

局部变量:定义在函数内部,只能在函数中使用的变量,作用范围是从函数开始到结尾,即在**{}**里。
这里定义的a就是局部变量。

function myTest1(){
    var a = 3;
    return a;
} 
console.log(a);//a is not defined
console.log( myTest1());//3

全局变量:常常定义在函数外部,拥有全局作用域,即在 JavaScript 代码的任何地方都可以访问

这里定义的b就是局部变量。

var b = 3;//全局变量
function myTest2(){
     return b;
 } 
console.log(b);//3
console.log(myTest2());//3

从这里我们就可以知道,函数内部可以调用全局变量,但是函数外部无法读取函数内的局部变量

函数内部声明变量的时候,必须使用var命令去声明一个变量。如果不用的话,就会声明了一个全局变量

function myTest3(){
    var c = 4;
    d=3;
    return c,d;
}
console.log( myTest3());//4,3
console.log(d);//3
console.log(c);//c is not defined

在这里我们cd都是在函数内部声明的,但是因为c使用了var,而d没有使用var声明,所以在外部能够使用d;也就是所谓的声明了一个全局变量


闭包

在理解了全局变量局部变量之后,我们先写一个简单的闭包实例给大家看看:

function myTest4(){
    var i = 4;
    return function(){
        return i;
    }
}
var func = myTest4();
console.log(func());//4

在这里我们是不是有点明白了呢:如果我们想用一个变量或者得到一个变量,但是我们又不想全局声明定义这个变量,到这的时候我们就可以通过闭包来调用函数内部的变量。

但是我们也应该知道闭包产生的值是一直保存在内存中的。这里通过一个例子给大家看看:

function myTest5(){
    var i = 4;
    return function(){
        return i++;
    }
}
var func = myTest5();
func();//4
func();//5
console.log(func());//6  

这个例子就是说调用一次,然后i的值就变了一次并且会一直被保存,然后下次调用的时候就是上次保存的值了。

一些闭包实例:

/* 例子1 */

function outerFn(){
  var i = 0; 
  function innerFn(){
      i++;
      console.log(i);
  }
  return innerFn;
}
var inner = outerFn();  //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
inner(); //1
inner(); //2
inner(); //3
var inner2 = outerFn();
inner2(); //1
inner2(); //2
inner2(); //3

/* 例子2 */

function m1(){
     var x = 1;
     return function(){
          console.log(++x);
     }
}
 
m1()();   //2
m1()();   //2
m1()();   //2
 
var m2 = m1();
m2();   //2
m2();   //3
m2();   //4

/* 例子3 */

var lis = document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
  (function(i){
      lis[i].onclick = function(){
           console.log(i);
      };
  })(i);       //事件处理函数中闭包的写法
}  

回收

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

一个简单的回收实例:

function myTest6(){
     var i = 4;
     return function(){
         return i++;
     }
 } 
 var func = myTest5();
 console.log(func());//4
 func = null;//n被回收
 var func = myTest5();
 console.log(func());//4

总结:

从作用上:

​ **作用1:**隐藏变量,避免全局污染

​ **作用2:**可以读取函数内部的变量

同时闭包使用不当,优点就变成了缺点:

缺点1:导致变量不会被垃圾回收机制回收,造成内存消耗

缺点2:不恰当的使用闭包可能会造成内存泄漏的问题


基于hexo搭建的一个博客:https://nanxiangscholar.github.io/
欢迎访问!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值