作用域和闭包

执行上下文

针对一段 script 标签或者一个函数而言

  • JS只有全局作用域和函数作用域(在 es6 之前)

  • 使用 var 声明的变量会在执行之前提升到作用域的最顶端。

  • 即可以在函数声明之前调用函数。在变量声明之前调用变量(此时变量的值为 undefined )。

  • 函数还包括 this,arguments

this

只有在执行的时候才能确定。包括赋值引用。注意区分构造函数内部的 this

可以通过 call, apply , bind 来改变 this 的指向。

闭包

返回一个函数或者传入一个函数去执行。都可以称之为闭包。

在这个闭包函数内部,可以定义变量来防止外部污染。即,私有变量。

不过需要注意内存泄露问题,因为在这边定义的变量无法自动释放。

function F1() {
  var a = 100;
  return function () {
    console.log(a); // 自由变量,取父级作用域中的值。
  };
}

var f1 = F1();
var a = 200;
f1(); // 100

创建 10 个标签,注入点击事件,分别按顺序输出 1-10

var i;

for (i = 0; i < 10; i++) {
  (function (i) {
    var a = document.createElement("a");
    a.innerHTML = i + "<br>";
    a.addEventListener("click", function (e) {
      e.preventDefault();
      alert(i);
    });
    document.body.appendChild(a);
  })(i);
}

新的 es6 可以用 let 来解决这个问题。

for (let i = 0; i < 10; i++) {
  var a = document.createElement("a");
  a.innerHTML = i + "<br>";
  a.addEventListener("click", function (e) {
    e.preventDefault();
    alert(i);
  });
  document.body.appendChild(a);
}