JS 闭包 - 83015010/js GitHub Wiki

JS-闭包

参考资料:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

闭包的作用

1 能够在外部得到某个函数的内部变量。

例:

    function Person() {
        var age = 1;
    }

    console.log(' age: '+age);

报错:Uncaught ReferenceError: age is not defined.因为 age在Person内部定义,外部无法获取

使用闭包来获取age

    function Person() {
        var age = 1;

        //person函数内部再定义个函数,用来获取age
        function getAge() {
            return age;
        }

        return getAge; //将函数返回
    }

    var persion = new Person(); 
    console.log(persion());  // persion() = getAge()

2 让变量的值始终保持在内存中

    function Person() {
        var age = 1;

        //person函数内部再定义个函数,用来获取age
        function getAge() {
            return age++;
        }

        return getAge; //将函数返回
    }

    var persion = new Person();
    console.log(persion());
    console.log(persion());
    console.log(persion());

输出结果:

1
2
3

原因:getAge()函数被赋值给了全局变量persion,这导致了getAge()一直会在内存中,而getAge()依赖于Person,所以Person也始终在内存中。

如果这样写:

    function Person() {
        var age = 1;
        return age++;
    }

    console.log(Person());
    console.log(Person());
    console.log(Person());

结果将是:

1
1
1

因为每次执行 console.log(Person());后 函数的调用已经结束,函数和内部的变量都被回收,下次再调用,生成的是新的函数和变量。

闭包的注意点:

1 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

闭包中的this

一句话概括this关键字:谁调用,指向谁。

例1

 var name = "Jack";
  var person = {
    name : "Tom",
    getName : function(){
      return function(){
        return this.name;
      };
    }
  };
   console.log(person.getName()());

代码分析:

var nameFunction = person.getName();
nameFunction();// ==window.nameFunction();
this由window调用。this.name = window.name = 'Jack'

例2:

    var name = "Jack";
    var person = {
        name : "Tom",
        getName : function(){
            var that =this;
            return function(){
                return that.name;
            };
        }
    };

    console.log(person.getName()());

代码分析:

var nameFunction = person.getName();
此时function中this为person。
that = this
that = person

再执行nameFunction()
得到that.name
即person.name
输出'Tom'