javascript中的【变量作用域】和【作用域链】以及【闭包】的理解

来源:互联网 发布:小米vr眼镜vb好不好 编辑:程序博客网 时间:2024/06/10 03:14
/*    变量作用域:        全局变量,定义在javascript最顶层的变量,都是全局变量。全局变量的作用范围在任何代码快中都能够使用。他的作用域        是全局性的。        局部变量,定义在函数中的变量,都是全局变量,局部变量作用域范围仅仅是在其函数内部和嵌套的函数内部能够使用。他        的作用域是局部性的。   作用域链:        每块javascript代码都有一个与之相关联的作用域链,这个作用域链是一组对象列表或链表,这组对象定义了作用域中的        “变量"。         当javascript查找变量x值的时候,他会从作用域链表中的第一个对象开始查找,如果第一个对象中存在,则返回该变量的         值,如果不存在,则会查找链表中的第二个对象并从第二个对象中查找变量x,若查到则返回,若查不到则以此类推从链表        中的下一个对象开始查找,若最终没有找到,则会抛出一个引用错误异常。        在javascript最顶层的代码中,作用域链由一个全局对象组成。在一个非嵌套的函数代码中,作用域链由两个对象组成,一        个是保存函数局部变量和参数的对象,一个是全局对象。在一个嵌套的函数代码中,作用域链由至少三个对象组成。        当定义一个函数时,都会有一个对象来保存局部变量。当调用函数时,会创建一个新的对象来保存局部变量并存放到作用域        链上,并会创建一个新的更长的表示该函数的作用域链。每次调用外部函数时,内部函数的作用域链一是不同的。 */ /*    闭包:       从闭包作用上来讲:            闭包就是js外部程序可以操作函数内部局部变量的一个特性。        闭包是关联函数对象的:           从闭包的特性来看,闭包是关联到函数对象的。如果想从原理上了解闭包,我们必须了解什么是变量作用域?什么是作           用域链?关于作用域链和变量作用域看上述详解。        闭包实现方式(从内存角度来理解或从垃圾回收机理解):            若要操作函数内部的局部变量,函数必须返回一个对象引用,并且被返回的对象中有操作局部变量的实现。当调用该函            数时,并且没有将其赋值给其他变量,则该函数执行完之后,其返回的对象和其内部种的作用域链对象会被垃圾回收。            若调用该函数并将其赋值给外部程序的一个变量,则该返回该对象的引用就是这个变量。所以不会被垃圾回收,所以该            对象所关联的作用域链也不会垃圾回收,所以外部的程序可以操作函数内部的局部变量。  */ function counter(){     var n=0;  //局部变量会被当成属性被存放到作用域链对象中的对象中;     return {  //返回一个对象,该对象可以操作局部变量n;         count:function(){return n++},         reset:function(){n=0}     } }/*   若直接调用该函数,该函数会创建一个新的对象存放其局部变量,并把该对象存放到作用域链对象中    该函数执行完毕后,会被垃圾回收。 */console.log(counter().count());/*   若将该闭包赋值给一个变量引用,则该函数对象不会垃圾回收。因为有外部引用使用着该对象,所以可以操作counter()函数   中的局部变量n,这种实现的方式就是利用  闭包 这个特性 */var a=counter();var b=counter();//a b两个对象互不影响。console.log(a.count());  //0console.log(a.count());  //1b.reset();console.log(a.count());//2a.reset();console.log(a.count());//0
0 0
原创粉丝点击