闭包与作用域

闭包与作用域

谈到闭包就肯定要联系到作用域,因为产生闭包就肯定和作用域有关,一直听别人讲闭包,也一直在学习中不断地学习闭包,现在就根据自己的理解浅聊一下闭包。

一、作用域

变量作用域分为局部作用域和全局作用域

var a=1;//a是全局变量
var f=function (){
     var b=2;//b是局部变量
     c=3;//c 是全局变量(c 没用var声明,是一个全局变量)
     a=4;//声明一个与与全局变量同名的局部变量a
    alert(a);//a=4
    alert(b);//b=2
} 
f();

alert(c);//c=3
alert(b);//出错

作用域链:代码在一个环境中执行时会创建变量的一个作用域链

var f1=function(){
    var local='local 1';
    var f2=function(){
        var local='local 2';
        var f3=function(){
            console.log(local);
        };
        f3();
    }
    f2();
}
f1();
//  local 变量在f3()函数内找不到,继而在f2(),如果f2()中未定义就会到
f1()中寻找,一直向上到全局作用域,这样就构成了一条作用域链。

二、闭包

实现外部作用域访问内部作用域中变量的方法就是闭包,在Javascript语言中,只有函数内部的子函数才能读取局部变量,也就可以理解为定义在函数内部的函数

var a="global scope";
var f=function(){
    var a="local scope";
    function f1(){return a};
    return f1();
}
f2=f;
f2();//f2()调用实现访问f内部变量

闭包最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,只有当相应的闭包对象被删除时才能在内存中被回收。一般只有在绝对必要时才建议使用闭包。

实现块级作用域

(function(){
     ......//这里是一个块级作用域
})();//块级作用域也称为私有作用域,可以模仿实现私有变量

通过闭包实现块级作用域和私有变量

function counter(){
    var n=0;
    return {
        count:function(){return n++;},
        reset:function(){n=1;}
    };
}
var c=counter(),d=counter();
c.count();//0
d.count();//0
c.reset();
d.count();//1
c.count();//0 counter函数返回计算器对象,这个对象含两个方法,这两个方法都可以访问私有变量n。每次调用counter()就会创建一个新的作用域链和新的私有变量。

三Javascript的垃圾回收机制

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

原文地址:https://www.cnblogs.com/LeeDou/p/5961398.html