闭包是函数?函数就是闭包?理论和实践中的闭包理解不太一样

本文是文字推理,并不是为了帮助你很好的去理解闭包

最近重新复习JS基础,在MDN上对于闭包的解析里看到这样一句话 :在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

意思是在JS中所有的函数都有一个闭包?

而翻开红宝书,对闭包的解释:闭包是指有权访问另一个函数作用域中变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

综合上面两句解析,我得到一些结论,然后我们看看这些结论对不对

  • 闭包是函数

    由红宝书中的解析得到:闭包是指有权访问另一个函数作用域中变量的函数

  • 函数是闭包

    因为每当创建一个函数,闭包就会在函数创建的同时被创建出来(创建一个函数,就有了函数,也有了闭包,这个闭包能访问另一个函数作用域中变量)

    又因为闭包是函数(红宝书权威解析!)

    所以函数是闭包?

来证明一下函数是闭包?

在JS中创建函数我们有两个场景,一个是在全局,一个是在函数内部(常见方式先略过)。

我们在全局创建一个函数,这个函数就是一个闭包了吗?

image.png 得出结论fun函数就是一个闭包,因为:

  • 有权访问另一个函数作用域(不太严谨这里是全局作用域)
  • 是一个函数

这时候把我给整懵了,最后又翻了下《JavaScript权威指南》看到这样一句话:

从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。

所以闭包是函数,函数就是闭包,这两个结论都没有毛病。

但是会和我们平时认知中的闭包不太一样,一直以为只有这样的才是闭包:

function outside(){
  const str = 'haha';
  return function inside(params) {
    console.log(str); // 内部函数访问外部函数的作用域(也算是闭包)
  }
}
outside()(); // 外部访问outside的内部变量
复制代码

其实这才是实践中的闭包,也是通常被我们巧妙运用的闭包。即能在外部访问某个函数内部变量。 而之所以能访问到内部变量,是因为这个函数存在一个内嵌函数及该内嵌函数存在对父作用域的引用(哈哈,绕的有点晕的,其实理解基本的原理就行),以此构成一个我们实践意义上的闭包。

看上面的代码,理论上outside和inside都是闭包,实践中我们习惯把inside称为闭包。

总结一下

理论上:闭包是函数,函数就是闭包。

实践中:闭包是一个内嵌函数,存在对父作用域的引用。

概念的理解通常会比较多问题,还望大家帮忙指出!

分类:
前端
标签: