深刻理解javascript原型和闭包(14)——从【自由变量】到【做用域链】

先解释一下什么是“自由变量”。javascript

在A做用域中使用的变量x,却没有在A做用域中声明(即在其余做用域中声明的),对于A做用域来讲,x就是一个自由变量。以下图html

如上程序中,在调用fn()函数时,函数体中第6行。取b的值就直接能够在fn做用域中取,由于b就是在这里定义的。而取x的值时,就须要到另外一个做用域中取。到哪一个做用域中取呢?前端

有人说过要到父做用域中取,其实有时候这种解释会产生歧义。例如:java

 

因此,不要在用以上说法了。相比而言,用这句话描述会更加贴切——要到建立这个函数的那个做用域中取值——是“建立”,而不是“调用”,切记切记——其实这就是所谓的“静态做用域”。web

对于本文第一段代码,在fn函数中,取自由变量x的值时,要到哪一个做用域中取?——要到建立fn函数的那个做用域中取——不管fn函数将在哪里调用。面试

 

上面描述的只是跨一步做用域去寻找。json

若是跨了一步,还没找到呢?——接着跨!——一直跨到全局做用域为止。要是在全局做用域中都没有找到,那就是真的没有了。闭包

这个一步一步“跨”的路线,咱们称之为——做用域链app

咱们拿文字总结一下取自由变量时的这个“做用域链”过程:(假设a是自由量)webapp

第一步,如今当前做用域查找a,若是有则获取并结束。若是没有则继续;

第二步,若是当前做用域是全局做用域,则证实a未定义,结束;不然继续;

第三步,(不是全局做用域,那就是函数做用域)将建立该函数的做用域做为当前做用域;

第四步,跳转到第一步。

 

以上代码中:第13行,fn()返回的是bar函数,赋值给x。执行x(),即执行bar函数代码。取b的值时,直接在fn做用域取出。取a的值时,试图在fn做用域取,可是取不到,只能转向建立fn的那个做用域中去查找,结果找到了。

 

这一节看似很轻松的把做用域链引出来,并讲完了。之全部轻松是有前几节的基础,不然将很难解释。

接下来我们开始正式说说一直期待依旧的朋友——闭包。敬请期待下一节。

---------------------------------------------------------------------------

本文已更新到《深刻理解javascript原型和闭包系列》的目录,更多内容可参见《深刻理解javascript原型和闭包系列》。

另外,欢迎关注个人微博

学习做者教程:《前端JS高级面试》《前端JS基础面试题》《React.js模拟大众点评webapp》《zepto设计与源码分析》《json2.js源码解读

相关文章
相关标签/搜索