每个函数在被调用时都会创建一个执行环境。执行环境有它的可变对象和作用域链。通过作用域链,可以访问上层作用域的内容。闭包的概念:闭包是一个函数,它可以访问另一个函数(这个“另一个函数”,通常是指包含闭包函数的外部函数)作用域内的变量functionouterFunction(){vara=1returnfunction(){console.log(a);}}varinnerFunction=outerFunction();innerFunction();本例中:负责打印a的匿名函数被包裹在外层函数outerFunction中,访问外层函数outerFunction作用域内的变量a,所以根据定义,它是一个闭包。再来说说函数执行环境、作用域链和变量对象(作用域和执行环境其实是同一个概念)。首先引用《javaScript高级语言程序》中的两句原话:“当一个函数被调用时,会创建一个执行环境(executioncontext)和对应的作用域链(scopeChain)”——7.2Closuresonpage178“每个执行环境有一个与之关联的变量对象,环境中定义的所有变量和函数都存储在这个对象中”——第73页4.2执行环境及其作用域执行环境(executioncontext)、作用域链(scopeChain)和变量object(变量对象),但是这三个Woolencloth是什么关系呢?汤姆大叔文章中的伪代码:ExecutionContext={variableObject:{....},this:thisValue,Scope:[//Scopechain//Listofallvariableobjects]};所以,当函数被调用时,会创建一个函数执行环境,其中有对应的变量对象和作用域链。每个函数的变量对象保存了它拥有的数据,供函数内部访问和调用。这些数据包括:(位于执行环境内部)1.声明变量2.声明函数3.接收参数例如:functionfoo(arg){varvariable='Iamavariable';functioninnerFoo(){alert("我是澎湖湾")}}foo('我是参数');这时执行环境对应的变量对象就变成了这样:,scope:[//作用域链//所有变量对象列表]};作用域链的作用:通过作用域链,函数可以从它的上层作用域(执行环境)访问变量见一个例子:functionfoo(){vara=1;functioninnerFoo(){console.log(a)}innerFoo();}foo();//Print1作用域链实际上是一个列表,从当前函数的变量对象开始,从内向外提取所有变量对象。通过这个作用域链表,可以实现对上层作用域的访问。Closuresandfunctioncurrying:多层嵌套的闭包,这种用法叫做“currying”。而闭包柯里化有两个作用:参数积累和延迟调用}}}foo('我')('叫')('澎湖湾');//printMynameisPenghuwan从这里可以直观的看出闭包柯里化时参数累加的作用。我们把上面的一个例子改一下:functionfoo(a){returnfunction(b){returnfunction(c){console.log(a+b+c);}}}varfoo1=foo('i');varfoo2=foo1('呼叫');foo2('澎湖湾');//打印我的名字是澎湖湾。可以看到在调用外层函数foo和foo1的时候并没有调用最内层的闭包,直到最后得到foo2,而当foo2()被调用时,最内层的闭包被执行,这也是闭包的一大特点——延迟执行https://www.cnblogs.com/pengh...
