canvascat / note

Learning Notes 🥱
3 stars 1 forks source link

闭包 #20

Open canvascat opened 3 years ago

canvascat commented 3 years ago

闭包 是指内部函数总是可以访问其所在的外部函数中声明的变量和参数,即使在其外部函数被返回(寿命终结)了之后。 通常,闭包会使用一个特殊的属性 [[Environment]] 来记录函数自身的创建时的环境的函数。它具体指向了函数创建时的词法环境。

在 JavaScript 中,所有函数都是天生闭包的。也就是说:JavaScript 中的函数会自动通过隐藏的 [[Environment]] 属性记住创建它们的位置,所以它们都可以访问外部变量。(但有一个例外,如果我们使用 new Function 创建一个函数,那么该函数的 [[Environment]] 并不指向当前的词法环境,而是指向全局环境)。

function getFunc() {
  const value = 'test';

  const func = new Function('alert(value)');
  const _func = function () {
    alert(value);
  };

  return { func, _func };
}

getFunc().func(); // Uncaught ReferenceError: value is not defined
getFunc()._func(); // "test",从 getFunc 的词法环境中获取的

在面试时,前端开发者通常会被问到“什么是闭包?”,

  1. 正确的回答应该是闭包的定义: 内部函数总是可以访问其所在的外部函数中声明的变量和参数
  2. 并解释清楚为什么 JavaScript 中的所有函数都是闭包的, 所有函数都有名为 [[Environment]] 的隐藏属性,该属性保存了对创建该函数的词法环境的引用。
  3. 以及可能的关于 [[Environment]] 属性和词法环境原理的技术细节。 使用 new Function 创建的函数,它的 [[Environment]] 指向全局词法环境,而不是函数所在的外部词法环境