如何理解javascript closure ?

简介: 既然javascript closure如此重要,那么问题来了,什么是closure呢?closure有什么作用?本文将结合我自己对closure的理解,用尽量通俗易懂的方式来进行阐述。

  接触过javascript的人应该听过闭包(closure),有一种观点认为是闭包赋予了javascript的强大能力,也赋予了它具备OOP的特征。既然javascript closure如此重要,那么问题来了,什么是closure呢?closure有什么作用?本文将结合我自己对closure的理解,用尽量通俗易懂的方式来进行阐述。

  先看看老外对closure怎么定义的?A closure is an inner function that has access to the outer (enclosing) function's variables—scope chain.从字面上来看,可以翻译为:闭包就是一个内部函数,它具备访问外部函数变量(这些变量位于作用域链中)的能力[注意变量不包含this和arguments]。但这个概念还是过于“专业化”, 不接地气,只从概念上来看,非常抽象。下面用一段JS来对应解释闭包的概念:

1.jpg个人理解为:fInner函数定义在fOuter的内部,可以访问fOuter定义的变量,这个fInner函数就是closureclosure的scope chain有3个一个是fInner函数定义的变量;一个是外部fOuter的变量;还有一个是全局变量(global variables)。closure的作用可以保留变量的值换句话说,函数fInner就是一个closure

closure可以干2件事情:

1)closure可以调用(闭包存储的外部变量是引用而不是值,这点非常重要)在当前函数以外的定义的变量(即使外部函数已经返回);

2)closure可以修改外部定义的变量值

下面通过一段JS代码来阐述为什么闭包存储的外部变量是引用而不是值,这点非常重要

functionmixFunction(a)
    {
varresult=[],i,n;
n=a.length;
for(i=0;i<n;i++){
result[i]=function(){
//Closure对外部变量是引用console.log("for i="+i);
returna[i];//a[i-1]            }
        }
returnresult;
    }
varmixcall=mixFunction([10,20,30]);
varf=mixcall[0];
console.log(f());//?应该输出什么值

f()会输出 10么?答案是undefined!!! ,执行示例如下所示:

2.png

为什么是这样的呢? 因为闭包对i是引用,在for循环时,会不断更新i的值。即在调用f()后,i已经被修改为3 (i===3),而a[3]为undefined!! ,示例如下所示:

2.jpg

上述的代码始终会输出a[2]的值,也就是30。 那么问题来了?怎么解决该问题呢?这就要用到JS中的IIFE技术啦!IIFE技术来解决JS缺少块级作用域的解决方案如下代码所示:

functionmixFunctionFix(a)
    {
varresult=[],i,n;
n=a.length;
for(i=0;i<n;i++){
//IIFE技术来解决JS缺少块级作用域的解决方案            (function(j){
result[i]=function(){
//Closure对外部变量是引用console.log("for j="+j);
returna[j];
                }
            })(i)
        }
returnresult;
    }
varmixcall=mixFunctionFix([10,20,30]);
varf=mixcall[0];
console.log(f());//10

控制台执行JS文件,输出如下图所示:

3.png

相关文章
|
7月前
|
设计模式 JavaScript 前端开发
js开发:请解释闭包(closure)是什么,以及它的用途。
闭包是JavaScript中的关键特性,允许函数访问并操作外部作用域的变量,常用于实现私有变量、模块化和高阶函数。私有变量示例展示了如何创建无法外部访问的计数器;模块化示例演示了封装私有变量和函数,防止全局污染;高阶函数示例则说明了如何使用闭包创建能接收或返回函数的函数。
63 2
|
7月前
|
JavaScript 前端开发 Java
MooTools、Backbone、Sammy、Cappuccino、Knockout、JavaScript MVC、Google Web Toolkit、Google Closure、Ember、Batman 以及 Ext JS。
MooTools、Backbone、Sammy、Cappuccino、Knockout、JavaScript MVC、Google Web Toolkit、Google Closure、Ember、Batman 和 Ext JS 都是 JavaScript 框架,用于开发 Web 应用程序。它们分别提供了不同的功能和特性,以帮助开发者更高效地构建和维护 Web 应用程序。
58 2
|
7月前
|
自然语言处理 JavaScript 前端开发
JavaScript基础知识:什么是闭包(Closure)?
JavaScript基础知识:什么是闭包(Closure)?
59 0
|
7月前
|
JavaScript 前端开发 Java
学习Javascript闭包(Closure)
学习Javascript闭包(Closure)
48 0
|
JavaScript 前端开发 Java
学习Javascript闭包(Closure)
学习Javascript闭包(Closure)
|
JavaScript 前端开发 Java
javascript中的闭包closure详解
javascript中的闭包closure详解