您的位置:首页 > Web前端 > JavaScript

关于本人对javascript闭包的理解

2012-02-28 11:50 302 查看
1、闭包是指有权访问另一个函数作用域中的变量的函数。
从作用域链上看,一个函数A包含函数B,B有权利访问A中的变量。作为全局作用域的对象(window)如果想访问A中的变量,是不被允许的,可是它可以通过调用A函数,让B去访问A函数中的变量,以达到函数外部想访问函数内部的目的。
2、闭包常见的创建方式是:一个函数内部创建另一个函数(就是A包含B)。
3、从微观角度去分析闭包。
1)、当定义了函数A,如果A是一个全局函数,在创建执行环境的过程中,全局执行环境中的变量对象,包含(this<window对象>,函数A,以及用以调用函数A的变量);
2)、然后又在全局作用域中调用函数A,在执行环境中会创建一个活动对象(包含this(一般是全局对象window,全局变量也始终存在,在创建函数 前,作用域链就始终包含window对象),为活动对象添加arguments属性<它保存着调用函数A时所传递的参数>,函数传入的参 数),创建完活动对象后,把活动对象添加到A的作用域链的最顶端。自此,函数A创建完成。此时A的作用域链包含了两个对象:A的活动对象和window对 象。
3)、接着定义函数A内部的函数B,根据javascript作用域链的访问规则,函数B将包含函数(即函数A)的活动对象添加进自己的作用域链中,即函 数B拥有函数A的活动对象,这样在函数B内部就能访问函数A中定义的所有的变量和函数。以2)类推,在执行环境中会创建一个活动对象(包含this(一般 是全局对象window),A的活动对象(javascript机制中,对函数传递对象,只会是值传递,所以是函数A的活动对象的引用),为活动对象添加 arguments属性<它保存着调用函数B时所传递的参数>,函数传入的参数),创建完活动对象后,把活动对象添加到 B的作用域链的最顶端。调用函数B时,B的作用域链包含了3个对象:B的活动对象、A的活动对象和window对象。
4)、在函数A内部,会返回函数B的引用,然后函数A又返回给全局环境中的某值C,即会将B的引用赋给C。这样就导致函数B被C引用,函数B又依赖函数A的活动对象,使用者A中的变量或函数。
5)、因而函数A执行完毕的时候,因为函数B还引用着函数A的活动对象,所以尽管A执行完成,作用域链被销毁,可是其活动对象还被引用不能被销毁回收,仍 留在内存中,除非,匿名函数被销毁,才能使函数A的活动对象被销毁。如何能让匿名函数被销毁呢,只要解除对匿名函数的引用就可以,换句话说,就是让调用函 数A的引用值为null。
6)、因而,闭包中会携带包含着它的函数(即函数A)的作用域,导致内存要其他函数使用的内存要多,过多的使用闭包会导致内存占用过多,建议是必要时才使用。
4、当函数A的内部函数(即函数B)被函数A外的一个变量C引用的时候,就创建了一个闭包。可以浅显理解,B连着A,A连着C,C连着B,组成闭合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: