在上一节我们了解到了GO、AO, 这节的作用域、作用域链相当于个容器,他是用来装GO、AO的。

# 作用域 [[scope]]、作用域链 Scope Chain

作用域总结:

只要函数被定义,就生成相应的作用域和作用域链,然后GO放进去

只要函数被执行时(前一刻)就生成自己的AO,默认排在作用域链顶端(第0位)

内部函数被定义时拿的是父级作用域的环境

函数执行完成后AO是要销毁的,AO是一个即时的存储容器(闭包除外)

当前作用域没有找到定义,会向父级作用域寻找,直至全局作用域,这种层级关系,就是作用域链

GO 和 AO 拿的是一个地址(我去星巴克,拿的是那个通讯地址,不是我把星巴克的店铺帮来我家)


下面我们来详细剖析,看这一段代码。

# 作用域例子

function a() {
  function b() {}
  var a = 1;
}
var c = 3;
a();

1


2


3


4


5


6


7


8


# 闭包例子

闭包定义:

当内部函数被返回到外部并保存时,就会产生闭包,

闭包会造成原来的作用域不释放,

过度的闭包可能会造成内存泄漏或加载过慢。

内存泄漏:内存空间使用完毕之后未回收,这就叫做内存泄漏

人话:我手里捧着一盘沙子,沙子在手里有个洞一直漏,漏到地上越堆越多,这就叫做内存泄漏


例子2 带闭包的作用域

function test1(){
  function test2(){
    var b = 2;
    console.log(a);
  }
  var a = 1;
  return test2;
}
var c = 3;
var test3 = test1();
test3();

1


2


3


4


5

# 由于闭包是建立在一个函数内部的子函数,由于其可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,这时的子函数---也就是闭包,便拥有了访问上级作用域中的变量的权限,即使上级函数执行完后,作用域内的值也不会被销毁。

# 闭包案例:

例子1 累加累减

function test() {
  var n = 10;
  function add() {
    n++;
    console.log(n);
  }
  function reduce() {
    n--;
    console.log(n);
  }
  return [add, reduce];
}

var test1 = test();

test1[0]();
test1[0]();
test1[1]();
test1[1]();

例子2 日程安排

function sunSched() {
  var sunSched = '';
  var operation = {
    setSched: function (thing) {
      sunSched = thing;
    },
    showSched: function () {
      console.log('我星期天的上午安排是' + sunSched);
    }
  }
  return operation;
}

var sunSched = sunSched();
sunSched.setSched('跑步');
sunSched.showSched();

例子3 闭包配合立即执行函数(IIFE)

function test() {
  var arr = [];

  for (var i = 0; i < 10; i++) {
      arr[i] = function () {// 此时函数定义 并不会看内部内容。
        document.write(i + ' ');
      }
  }

  return arr;
}

var myArr = test();

for (var j = 0; j < 10; j++) {
  myArr[j]();// 10 个10 // 此时函数执行 在看AO内部内容 循环完i已经是10了
}
function test() {
  var arr = [];

  for (var i = 0; i < 10; i++) {
    (function (i) {
      arr[i] = function () {
        document.write(i + ' ');
      }
    })(i)
  }

  return arr;
}

var myArr = test();

for (var j = 0; j < 10; j++) {
  myArr[j]();// 0 - 9 
}

# 解除闭包:未完待续...