javascript闭包

原创 2016年05月30日 21:05:00

浅谈闭包

 

想弄清闭包,我们首先得知道我们为啥要用到闭包呢,我们想要在一个函数内部取到函数外部的变量,或者调用函数外部的方法都是很容易的,因为javascript查找变量或方法都是逆着作用域链向上查找的,但是我们现在有了这样一个需求:我们想在函数外面取到函数内部一个临时变量的值,这样的需求使得我们违背了javascript的基本原则。而闭包恰好帮助我们解决了这个问题。

 

接下来我们看一个例子:

function setName(){
    var name="CSDN";
    function getName(){
        return name;
    }
}

 

getName函数是不是取到了setName函数内部的临时变量,这确实是的。

 

我们再看一个经典的错误例子:

我们想在数组的每项上绑定一个函数,希望他执行的时候能一次打印0,1,2,,,9;

但是发现,他只能打印1010

function consoles(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=function(){
            console.log(i);
        }
    }
    return arr;
}

var arr=consoles();
for(var j=0;j<10;j++){
    arr[j]();
}

 

 

 

 

 

我们稍微把代码改一下:

 

 

 

function consoles(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=(function(num){
            return function(){
                console.log(num);}
        })(i)
    }
    return arr;
}

var arr=consoles();
for(var j=0;j<10;j++){
    arr[j]();
}

 

我们使得一个匿名函数自执行,返回一个函数给数组各项,这样就行了。

弄懂这两个基本可以理解闭包了,在讲这两个例子之前咋们还得说一个例子做一个铺垫~~(不要嫌我啰嗦啦。。。)

 

function setName(){
    var name="CSDN";
    function getName(){
        return name;
    }
}

 

这就是文章开头写的那个例子,如果我们直接在setName外面调用getName肯定是得不到name值的,但是如果我们这样稍稍变化一下呢,

function setName(){
    var name="CSDN";
    return function (){
        alert(name);
    }
}
var get=setName();
get();

 

我们在setName内部返回一个函数,在函数外部用get变量接受,继续调用get函数,打印CSDN,这样为什么就行了呢?原因就是我们返回的函数可能会被再次调用,所以他用到的setName的局部变量不会在setName调用完毕之后就被gc回收,局部变量name会常驻内存,当我们再次调用get函数即setName返回的函数,就会弹出”CSDN”;

我们这时候再回头看一下那个经典例子:

function consoles(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=function(){
            console.log(i);
        }
    }
    return arr;
}

 

为什么我们循环执for(j=0;j<10;j++){

arr[j]();

}

会打印10 10 呢?

我们在这个函数中返回的是一个数组,每个项都存着一个函数,这跟我们之前直接返回一个函数,再调用,是不是大同小异啊,我们返回的数组中的10个函数有可能会被再次调用,所以我们在consoles函数中定义的局部变量i,是不会在consoles执行完毕就被垃圾回收机制回收,在循环结束i的值为10,这个值会一直保存在内存中,当arr[j]()调用时就会寻找到这个i值,这样就会打印1010,如果我们在内部循环结束重新给i赋值1,这样就会打印10 1了,现在清楚点了吧~~

 

那为什么我们这样改一下就行了呢?

function consoles(){
    var arr=[];
    for(var i=0;i<10;i++){
        arr[i]=(function(num){
            return function(){
                console.log(num);}
        })(i)
    }
    return arr;
}

var arr=consoles();
for(var j=0;j<10;j++){
    arr[j]();
}

 

我们使用匿名函数的自执行,把i值传入匿名函数内部,我们返回的是表达式!这个表达式当然能够接收到我们传入的i值即num

 

闭包就是能够访问函数内部变量的函数,闭包有两个特点1他能够访问函数内部的变量2、她能让函数内部的变量常驻内存

正是由于这样我们才可以访问函数的局部变量,当闭包执行的时候,包含他的函数的执行环境会加入到闭包的执行环境中去,这个才是关键。。。。闭包越多消耗的内存就越多,因为她要保存包围他的函数的执行环境,所以不用闭包就要手动释放,通知垃圾回收机制回收内存,以免造成内存泄露。

真正要搞明白闭包,还是要清楚作用域链和函数的执行环境~~打好基础很重要~这样理解起来就会轻松一点了~~

版权声明:本文为博主原创文章,未经博主允许不得转载。

全面理解Javascript闭包和闭包的几种写法及用途

好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法、用法和用途。  一、什么是闭包和闭包的几种写法和用法 1、什么是闭包 闭...
  • zhangweiwtmdbf
  • zhangweiwtmdbf
  • 2016年02月16日 17:38
  • 2265

JavaScript 闭包小结

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应该是很有用的。 一、变量的作用域 ...
  • hellobinfeng
  • hellobinfeng
  • 2013年10月23日 06:30
  • 1124

JavaScript闭包详解

1.闭包概念及闭包作用域链  闭包是指有权访问另外一个函数作用域中的变量的函数。创建闭包的常见的方式,就是在函数内部创建另外一个函数。    function closure(arg){       ...
  • vuturn
  • vuturn
  • 2015年03月23日 10:55
  • 2238

Javascript 闭包完整解释

  • 2012年11月20日 15:30
  • 100KB
  • 下载

[JavaScript] 你不知道的 JS (作用域 &amp; 闭包) (英文版)

  • 2014年11月27日 09:07
  • 5.06MB
  • 下载

javascript闭包

  • 2011年06月04日 21:40
  • 546KB
  • 下载

深入理解javascript原型和闭包

  • 2015年11月30日 16:37
  • 1.17MB
  • 下载

javaScript闭包

  • 2012年03月22日 21:54
  • 1.03MB
  • 下载

javascript闭包详解

  • 2012年07月21日 10:53
  • 236KB
  • 下载

javascript 闭包

  • 2013年06月08日 07:15
  • 49KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript闭包
举报原因:
原因补充:

(最多只允许输入30个字)