什么是闭包?

  • 简而言之,闭包就是指有权访问另一个函数作用域中的变量的函数,并且让这些变量的值始终保持在内存中。

  • 常用的创建方法是在一个函数的内部创建另一个函数。like:

    function num1(){
        var n = 0;
           add = function(){
           n++;
           }
        function num2(){
          console.log(n);
        }
        return num2;
      }
      var result = num1();
      result(); // 0
        add();
        result(); // 1
    • 第一次result()的结果是0,第二次是1,因为num2是num1的子函数,它被赋予全局变量,因此会一直占用内存,而num2的内存依赖于num1,因此num1也一直占用内存。不会把第一次得到的n放入垃圾回收机制。

    • 另外add没有用var声明,因此它属于全局变量。

  • 由于闭包会携带包含它的的函数的作用域,因此会比其他函数占据更多的内存,所以为了性能,要慎用闭包。

垃圾回收机制

  • 在这里提一下上文说到的垃圾回收机制,原理很简单:找出那些不再继续使用的变量,释放其占用的内存。垃圾回收机制会按照固定的时间间隔,周期性地执行操作。

this对象

  • 在全局函数中,this等于window。而函数被当作某个对象的方法调用时(也就是非匿名函数),this指的是那个对象。但是,匿名函数的作用域是全局的。因此匿名函数的this指的是window。

  • 比如下面这个例子:

    var name="sara";
    var names={
        name:"Aom",
        sayName:function(){
           return function(){
             return this.name
           };
        }
    };
    alert(names.sayName()()); //"sara"
    • sayName()返回的是一个匿名函数,匿名函数的作用域是全局的,因此this.name返回的是sara。

    • 不过可以把sayName的外部函数的this保存在一个变量中,sayName的匿名函数调用这个变量代替this。就可以返回到外部函数的name。
      实现如下:

      var name="sara";
      var names={
              name:"Aom",
              sayName:function(){
              var self = this;
                 return function(){
                   return this.name
                 };
              }
      };
      alert(names.sayName()()); //"Aom"
  • this得值在几种特殊情况下也会改变。

    var name="sara";
    var names={
            name:"Aom",
            sayName:function(){
                 return this.name
            }
    };
    names.sayName();//"Aom"
    (names.sayName)();//"Aom"
    (names.sayName = names.sayName)();//"sara"
    • 第一种情况很简单,在这里就不做解释;第二种情况,因为(names.sayName)和names.sayName定义是相同的,所以结果是"Aom";第三种情况,括号内进行的赋值是sayName函数本身,并不会附带赋值names的其他内容,因此this发生了改变,取得window,结果为sara。


刘雯
58 声望10 粉丝

爱前端的kcoder