高级前端
js
【Q514】什么是闭包,闭包的应用有哪些地方

什么是闭包,闭包的应用有哪些地方

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 527 (opens in a new tab)

闭包是一个函数, 其可以记住并访问外部变量.

在函数被创建时, 函数的隐藏属性 [[Environment]] 会记住函数被创建时的位置, 即当时的词法环境 Lexical Environment

这样, 无论在哪里调用函数, 都会去到 [[Environment]] 所引用的词法环境

当查找变量时, 先在词法环境内部查找, 当没有找到局部变量时, 前往当前词法环境所记录的外部词法环境查找

我知道的闭包的应用: 封装私有变量和处理回调函数

前端新人, 理解浅薄, 如果有错希望您指出

学习来源为 JavaScript.info/Closure (opens in a new tab)

Author 回答者: shfshanyue (opens in a new tab)

TODO

Author 回答者: shfshanyue (opens in a new tab)

闭包是一个函数, 其可以记住并访问外部变量.

在函数被创建时, 函数的隐藏属性 [[Environment]] 会记住函数被创建时的位置, 即当时的词法环境 Lexical Environment

这样, 无论在哪里调用函数, 都会去到 [[Environment]] 所引用的词法环境

当查找变量时, 先在词法环境内部查找, 当没有找到局部变量时, 前往当前词法环境所记录的外部词法环境查找

我知道的闭包的应用: 封装私有变量和处理回调函数

前端新人, 理解浅薄, 如果有错希望您指出

学习来源为 JavaScript.info/Closure (opens in a new tab)

很专业了,像 once 这种记忆缓存数据的是否也算是一种应用

请问 once 指的是什么?

Author 回答者: shfshanyue (opens in a new tab)

@liweinandever

onetime (opens in a new tab) 或者 _.once (opens in a new tab),再加上 throttle/debounce 这种应该都是利用了闭包

闭包是一个函数, 其可以记住并访问外部变量. 在函数被创建时, 函数的隐藏属性 [[Environment]] 会记住函数被创建时的位置, 即当时的词法环境 Lexical Environment 这样, 无论在哪里调用函数, 都会去到 [[Environment]] 所引用的词法环境 当查找变量时, 先在词法环境内部查找, 当没有找到局部变量时, 前往当前词法环境所记录的外部词法环境查找 我知道的闭包的应用: 封装私有变量和处理回调函数 前端新人, 理解浅薄, 如果有错希望您指出 学习来源为 JavaScript.info/Closure (opens in a new tab)

封装私有变量

function Ninja() {
  // 私有变量
  let feints = 0;
 
  this.getFeints = () => {
    return feints;
  };
  this.feint = () => {
    feints++;
  };
}
const ninja1 = new Ninja();
const ninja2 = new Ninja(); // ninja1 和 ninja2 有自己的词法环境
 
console.log("Ninja", Ninja);
 
console.log("ninja1 not access feints", ninja1.feints === undefined); // true
console.log("get feints", ninja1.getFeints()); // 0
ninja1.feint(); // +1
console.log("get feints", ninja1.getFeints()); // 1

处理回调函数

function fn() {
  // tick 在这里被修改
  // Interval 的回调函数, 通过闭包找到这里
  let tick = 0;
  console.log("tick init", tick);
 
  const timer = setInterval(() => {
    if (tick < 100) {
      tick += 1;
      console.log("tick change", tick);
    } else {
      clearInterval(timer);
      console.log("tick equal 100", tick === 100);
      console.log("access timer by closure", timer);
    }
  }, 10);
}
fn();

来源: JavaScript 忍者秘籍 (opens in a new tab) 可以直接编辑的, 我忘记了, 引用了三次.

Author 回答者: illumi520 (opens in a new tab)

从作用域的角度理解,每创建一个函数会创建一个作用域,闭包里面的函数没有要释放,但是在外层却返回了本函数,导致变量不能被释放而留存下来,应用就是对于有存储变量的需求可以用

Author 回答者: yangzi0210 (opens in a new tab)

通俗的说就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。JS中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。能够在函数定义的作用域外,使用函数定义作用域内的局部变量,并且不会污染全局。 用处:它的最大用处有两个,一个是它可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。