力扣 30 天 JavaScript 挑战 第二题笔记

这道题是

涉及知识--闭包

1. 闭包定义以及相关知识点

官方定义为:在 JavaScript 中,函数具有对在相同作用域以及任何外部作用域中声明的所有变量的引用。这些作用域被称为函数的 词法环境。函数与其环境的组合被称为 闭包。

简单理解:内层函数+引用的外层函数变量。下图的a变量以及f函数就构成了闭包。

但是这样外部(这个外部是相对于outer而不是f)不可以使用闭包里面的变量,此时需要return。

复制代码
function outer(){
    let a = 1
    function f(){
     return a;
    }
    f()
}
const result = outer()

这样通过返回闭包里的函数,外部可以访问到a的值,实现了变量的私有化(在outer函数的外部不可以修改a的值,只能访问a的值)。

但是这样同样造成了内存泄露,因为一般来说函数执行完毕后,会立刻被回收,但是现在讲f赋值给了一个全局变量,不会被回收,造成了内存泄露。

2. 闭包vs类

上述函数类的写法为

复制代码
class outer {
  constructor() {
     this.a = 1;
  }

  add() {
     return this.a;
  }
}
const result = new outer()
  • 闭包和类的共同点
    都允许你定义或者传入一个私有数据,并且提供一个函数使用私有数据。
  • 闭包的优势 封装
    类里面可以通过 result.a=3来修改私有变量,但是闭包不可以。
  • 类的优势 节省内存
    类的方法存在"公共仓库"(原型对象)里,所有实例来借用。闭包每次造一个新实例,就重新拷贝一份方法。

答案

理解了闭包就很简单了

java 复制代码
/**
 * @param {number} n
 * @return {Function} counter
 */
var createCounter = function (n) {

    return function () {
        return n++
    };
};

/** 
 * const counter = createCounter(10)
 * counter() // 10
 * counter() // 11
 * counter() // 12
 */