在 JavaScript 中,闭包是一个常见且重要的概念,可以帮助我们编写更健壮、可读性更强的代码。但是,对于初学者来说,理解闭包可能会有一些挑战,尤其是当他们发现只有将返回的函数赋值给变量时才会发生闭包时。
什么是闭包?
简单地说,闭包是指一个函数能够访问并操作其外部作用域中的变量,即使函数在该作用域之外被调用。这意味着,即使外部作用域已经销毁,闭包仍然可以使用其中的变量。这种行为可以实现很多有用的功能,例如保护变量、创建私有变量和函数等。
为什么只有将返回的函数赋值给变量才会发生闭包?
下面让我们来看一个例子:
-- -------------------- ---- ------- -------- --------------- - --- ----- - -- ------ ---------- - -------- ------------------- -- - --- ------- - ---------------- ---------- -- -- - ---------- -- -- -
在上述代码中,createCounter
函数返回了一个匿名函数,它可以访问 createCounter
函数中定义的 count
变量。这个匿名函数被赋值给变量 counter
,并且可以在这个变量被调用时执行。
那么,如果我们不将返回的函数赋值给变量,会发生什么呢?请看下面的代码:
-- -------------------- ---- ------- -------- --------------- - --- ----- - -- ------ ---------- - -------- ------------------- -- - ------------------ -- -- - ------------------ -- -- -
在上述代码中,我们调用了两次 createCounter()
函数,并且每次都立即调用了返回的匿名函数。注意,在第二次调用 createCounter()
时,它返回的是一个全新的匿名函数。
为什么输出结果是 1 而不是 2 呢?原因是每次调用 createCounter()
时,它都会创建一个新的作用域,并在其中定义一个名为 count
的变量。因此,这两个匿名函数实际上并不共享同一个 count
变量。
只有将返回的函数赋值给变量后,才能够保留对外部作用域中的变量的引用。在我们的示例中,变量 counter
持有对匿名函数的引用,因此它可以在多次调用中维护 count
变量的状态。
总结
在 JavaScript 中,闭包是一个非常重要的概念,可以使我们编写更健壮、可读性更强的代码。当你将一个函数返回到它的外部作用域时,你创建了一个闭包。使用闭包时要注意变量作用域和生命周期,只有将返回的函数赋值给变量才能够保留对外部作用域中的变量的引用。
示例代码:CodePen
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/26183