JavaScript之作用域、立即执行函数与闭包

本文深入探讨了JavaScript中作用域、立即执行函数与闭包的概念。通过具体实例讲解了不同作用域下变量的访问机制,立即执行函数的用法及其在避免变量污染方面的作用,以及闭包如何创建及可能导致的内存泄漏问题。

作用域、立即执行函数:

AO:Activation Object , GO: Global Object

function a() {
      function b() {
        var bb = 234;
        aa = 0;
      }
      var aa = 123;
      b();
      console.log(aa);
    }
    var glob = 100;
    a();


    // GO: glob:undefined, 100,
    //     a:f a(){},
    //     b:f b() {},
    //     aa:undefined,123,0,

    // AO: bb:undefined,234,

    // 输出:
    // 0
function a() {
      var num = 100;

      function b() {
        num++;
        console.log(num);
      }
      return b;
    }

    var demo = a();
    demo();
    demo();

    // GO: a : f a(){},
    //     demo : undefined, f b(){},101,102

    // AO: num:undefined,100,
    //     b:f b(){},


    // 输出:
    // 101
    // 102

 
立即执行函数:
例如:执行完即销毁,再也找不到abc();

(function abc() {
  var a = 123;
  var b = 234;
  console.log(a + b);
}())

(function abc(a, b, c) {
  console.log(a + b + c);
}(1, 2, 3))

var num = (function abc(a, b, c) {
  var d = a + b + c;
  return d;
}(1, 2, 3))
console.log(num);

写法有几种?

(function () {}()); //W3C建议使用;
(function () {})();
var test = function () {}(); //test将找不到了..
+ function test() {}(); // + | - | !   test()将找不到..

注意:

function test(a) {
  console.log(a);
}()
// 报错

function test(a, b, c, d) {
  console.log(a + b + c + d);
}(1, 2, 3, 4)
// 不执行

 

闭包:
内部函数保存到了外部,就会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。

  • 实现公有变量
  • 可以做缓存
  • 可以实现封装,属性私有化
  • 模块化开发,防止污染全局变量

例1.先执行 var demo = a(); 得到aaa = 123;并把函数function b() {}抛给demo;再执行demo(); bbb=234;

function a() {
      function b() {
        var bbb = 234;
        console.log(aaa);
      }
      var aaa = 123;
      return b;
    }
    var glob = 100;
    var demo = a();
    demo();

    // GO: a: f a() {}
    //     glob: undefined,100
    //     demo: undefined,bbb:234,

    // AO:b:f b(){},
    //    aaa:undefined,123
    //    bbb:undefined,234

    // 输出:
    // 123,

 
例2.

function test() {
      var num = 100;

      function a() {
        num++;
        console.log(num);
      }

      function b() {
        num--;
        console.log(num);
      }
      return [a, b];
    }
    var myArr = test();
    myArr[0]();
    myArr[1]();

    // GO: test : f test() {},
    //     myArr: undefined,[f a(){},f b(){}]


    // AO: num: undefined ,100,101,100
    //     a: f a(){},
    //     b: f b(){},

    // 输出:
    // 101,
    // 100

 
例3.

function eater() {
      var food = "";
      var obj = {
        eat: function () {
          console.log("I am eating " + food);
          food = "";
        },
        push: function (myFood) {
          food = myFood;
        }
      }
      return obj;
    }
    var eater1 = eater();
    eater1.push('banana');
    eater1.eat();

    // GO: eater: f eater() {},
    //   eater1: undefined, {
    //     eat: f() {},
    //     push: f(myFood) {}
    //   }

    // AO: food: undefined, "", banana,
    //   obj: undefined, {
    //     eat: f() {},
    //     push: f(myFood) {}
    //   }

    // 输出:
    // I am eating banana

 
例4. 因为i最后为10,arr[i] = function () {console.log(i);} 中的
function () {console.log(i);}要在 return arr;后的 myArr (j)(); 才执行,
所以最后执行console.log(i); 全都是10.

function test() {
      var arr = [];
      for (var i = 0; i < 10; i++) {
        arr[i] = function () {
          console.log(i);
        }
      }
      return arr;
    }
    var myArr = test();
    for (var j = 0; j < 10; j++) {
      myArr[j]();
    }

    // GO: test : f test(){},
    //     myArr : undefined,[arr[0] f(){},...],
    //     j : 0,1...10

    // AO: arr : undefined,[arr[0] f(){},...],
    //     i : 0,1...10,


    // 输出:(十个10)

    // 10
    // 10
    // 10...

 
例5. 修改例4;

function test() {
      var arr = [];
      for (var i = 0; i < 10; i++) {
        (function (j) {
          arr[j] = function () {
            console.log(j);
          }
        }(i));
      }
      return arr;
    }
    var myArr = test();
    for (var j = 0; j < 10; j++) {
      myArr[j]();
    }
    // GO: test : f test(){},
    //     myArr : undefined,[arr[0] f(){},...],
    //     j : 0,1...10

    // AO: arr : undefined,[arr[0] f(){},...],
    //     i : 0,1...10,


    // 输出:
    // 1,2,3,4,5,...9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值