JavaScript闭包20171229

一 变量作用域

  • 2种作用域:全局&局部;
  • js链式作用域结构,函数内部可以直接读取全局变量;函数外部无法读取函数内的局部变量;
  • 函数内部声明变量,要用var,如果不用var,直接n=3,实际上是声明了一个全局变量;

二 如何从外部读取局部变量

  • 在函数A的内部,再定义一个函数B,函数B就可以引用函数A的局部变量(这有点像偷换概念啊。。)
function A(){
    var n=3;
    function B(){
        console.log(n);
    }
}
  • 既然B()可以读取A()中的局部变量,那么重要把B()作为返回值,就可以在A()外部,读取A的内部变量了;
function A(){
    var n = 3;
    function B(){
        console.log(n);
    }
    return B;
}
var re = A();
re();//3

三 闭包的概念

  • 上述,B函数,就是闭包;
  • 一个理解:闭包是 能够读取其他函数内部变量的 函数;——把函数内部和函数外部连接起来的一座桥梁;
  • 在JavaScript中,对于函数A,只有函数A内部的子函数(比如取名叫B)才能读取函数A内的局部变量(其实是函数B的外部变量);——简单理解:定义在一个函数内部的函数;

四 闭包用途-2个

  • 读取函数内部的变量;
  • 让这些变量的值始终保持在内存中;
    re,就是返回的闭包f2函数,一共运行了2次:第一次的值0,第二次的值1;这表示,函数f1中的局部变量n一直保持在内存中,没有在f1调用后自动清除;

    function f1(){
        var n=0;
        nAdd = function(){n+=1;}
        // 1 nAdd前面没有var,所以它是一个全局变量;
        // 2 nAdd的值,是一个匿名函数,这个匿名函数本身也是一个闭包----nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作;
        function f2(){
            console.log(n);
        }
        return f2;
    }
    var re = f1();
    re();//0
    nAdd();
    re();//1
    
    var name = "我的window";
    var object = {
        name:"my object",
        getNameFunc:function(){
            return function(){
                return this.name;
            };
        }
    };
    object.getNameFunc()()//"我的window"
    
    var name = "我的window";
    var object = {
        name:"my object",
        getNameFunc:function(){
            var that = this;
            return function(){
                return that.name;
            }
    
        }
    };
    object.getNameFunc()();//"my object"
    

发表评论