6.3 闭包

一个“变量”只是 环境记录 这个特殊的内部对象的一个属性。“获取或修改变量”意味着“获取或修改词法环境的一个属性”。

所有的函数在“诞生”时都会记住创建它们的词法环境。

闭包 是指内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函数被返回(寿命终结)了之后。

函数将从内到外依次在对应的词法环境中寻找目标变量,它使用最新的值。

6.4 var

var 只有函数作用域和全局作用域,没有块级作用域

var 允许重复声明

var 变量声明会提升,但赋值不会

IIFE 立即执行函数创建私有变量(现在已不使用)

  1. // 创建 IIFE 的方法
  2. (function() {
  3. alert("Parentheses around the function");
  4. })();
  5. (function() {
  6. alert("Parentheses around the whole thing");
  7. }());
  8. !function() {
  9. alert("Bitwise NOT operator starts the expression");
  10. }();
  11. +function() {
  12. alert("Unary plus starts the expression");
  13. }();

6.6 函数 NFE

命名函数表达式(NFE,Named Function Expression)

方便函数自己调用自己,且该名称不能在外部访问

  1. let sayHi = function func(who) {
  2. if (who) {
  3. alert(`Hello, ${who}`);
  4. } else {
  5. func("Guest"); // 使用 func 再次调用函数自身
  6. }
  7. };
  8. sayHi(); // Hello, Guest
  9. // 但这不工作:
  10. func(); // Error, func is not defined(在函数外不可见)

6.7 new Function([arg1,arg2], functionbody)

使用 new Function 创建的函数,它的 [[Environment]] 指向全局词法环境,而不是函数所在的外部词法环境。
因此,我们不能在 new Function 中直接使用外部变量。

6.8 调度函数

任何 setTimeout 都只会在当前代码执行完毕之后才会执行。

6.10 函数绑定

一个函数不能被重绑定(re-bound)

  1. function f() {
  2. alert(this.name);
  3. }
  4. f = f.bind({ name: "John" }).bind({ name: "Pete" });
  5. f(); // John

bind 的结果是另一个对象。

  1. function sayHi() {
  2. alert(this.name);
  3. }
  4. sayHi.test = 5;
  5. let bound = sayHi.bind({
  6. name: "John",
  7. });
  8. alert(bound.test); // undefined