闭包

来源:互联网 发布:网络显卡联机 编辑:程序博客网 时间:2024/06/15 00:03

一、概述

  • 闭包是指有权访问另一个函数作用域中变量的函数
  • 在一个函数内部创建另一个函数,即可创建闭包
function f1(num){    function f2(){        console.log(num);    }    f2();}f1(5);
  • 要理解闭包,必须要清楚作用域链。在上面的例子中,先定义了f1函数,然后又在全局作用域中调用了它,当调用f1时,会创建一个arguments、num的活动对象。

这里写图片描述

  • 在f2调用时,它的作用域被初始化为包含f1的活动对象和全局变量对象。这样,f2就可以访问在f1中定义的所有变量。最重要的是,f1在执行完毕后,其执行环境的作用域链会被销毁,但是它的活动对象仍然会留在内存中,直到f2被销毁后,f1的活动对象才会被销毁。

这里写图片描述

二、闭包与变量

  • 闭包只能取得包含函数中农任何变量的最后一个值,例如:
function f1() {    var result = new Array();    for(var i = 0; i < 10; i++) {            result[i] = function(){                return i;            }        }    return result;}

这个函数会返回一个函数数组。一眼望去答案应该是1,2,3……,但实际上都返回10。因为每个函数的作用域链中都保存着f1的活动对象,所以他们引用的都是同一个变量i。

  • 要想依次输出1,2,3……,我们课可以通过创建另一个匿名函数强制让闭包的行为符合预期。
function f1() {    var result = new Array();    for(var i = 0; i < 10; i++) {            result[i] = function(num){                return function(){                    return num;                };            }(i);        }    return result;}

在上面代码中,在调用每次匿名函数时,我们都传入了变量i,由于函数参数是按值传递的,所以就会将变量i的当前值复制给参数num。而在这个匿名函数内部,又创建并返回了一个访问num的闭包。这样一来,result数组中的每个函数都有自己num变量的一个副本,因此就可以返回不同的值。

原创粉丝点击