---恢复内容开始---
首先得从词法作用域说起
词法作用域就是函数是通过词法区分作用域的。是在定义的位置执行的,而不是在调用的位置执行的。
调用对象和全局对象
调用一个函数时,会将其作用域设置为其起作用的作用域链,并且在该作用域链前添加一个调用对象。
作为闭包的嵌入函数
想象一个嵌套在函数f里的函数g,f被调用时,其作用域包含了对f这一调用的调用对象,后边是全局对象。而当g被调用时,因为要回到f中定义g的位置,而g只有f调用时会被定义,也就是f的调用对象是g的定义位置的一部分。。所以g的作用域链包含了g的调用对象、f的调用对象、全局对象
考虑下列代码
1 var x = 0; 2function outer() { 3 x++; 4 if(x == 1) { 5 function inner() { 6 console.log(x); 7 } 8 return inner; 9 } 10} 11 12 var inner = outer(); 13 inner();
为什么能返回1
将outer函数调用并赋予inner,也就是outer中的inner函数给了inner变量,然后调用inner变量,调用后会回到第5行定义inner函数的地方,由于inner的定义是outer调用时执行的,那么outer的调用对象就是定义的位置的一部分,也同时包含了x++语句,即当时定义时的外围的变量的值都是保留着的。此时的x=1,inner函数执行其中语句,开始顺着作用域寻找x的值,找到第3行发现x为1,于是输出打印1.
总结:
闭包虽然是个名词,在javascript中将其描述为将要执行的代码以及这些代码的作用域构成的一个综合体,这个综合体叫做闭包。所有的js函数都叫闭包
但是只有一个函数被导出到它所定义的作用域外时,这种技术才有研究的意义,所以一般都将闭包称为一种一个作用域能够调用读取另一个函数中的变量的现象
---恢复内容结束---