先解释一下什么是“自由变量”。
在A作用域中使用的变量x,却没有在A作用域中声明(即在其他作用域中声明的),对于A作用域来说,x就是一个自由变量。如下代码块:

var x = 10;
function fn(){var b = 20;console.log(x + b);// 这里的x在这里就是一个自由变量
}

如上程序中,在调用fn()函数时,函数体中第6行。取b的值就直接可以在fn作用域中取,因为b就是在这里定义的。而取x的值时,就需要到另一个作用域中取。到哪个作用域中取呢?

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

var x = 10;
function fn(){console.log(x);
}
function show(f){var x = 20;(function (){f(); //10, 而不是20})();
}
show(fn());

所以,不要在用以上说法了。相比而言,用这句话描述会更加贴切——要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”,切记切记——其实这就是所谓的“静态作用域”。
对于本文第一段代码,在fn函数中,取自由变量x的值时,要到哪个作用域中取?——要到创建fn函数的那个作用域中取——无论fn函数将在哪里调用。

上面描述的只是跨一步作用域去寻找。
如果跨了一步,还没找到呢?——接着跨!——一直跨到全局作用域为止。要是在全局作用域中都没有找到,那就是真的没有了。
这个一步一步“跨”的路线,我们称之为——作用域链。
我们拿文字总结一下取自由变量时的这个“作用域链”过程:(假设a是自由量)
第一步,现在当前作用域查找a,如果有则获取并结束。如果没有则继续;
第二步,如果当前作用域是全局作用域,则证明a未定义,结束;否则继续;
第三步,(不是全局作用域,那就是函数作用域)将创建该函数的作用域作为当前作用域;
第四步,跳转到第一步。

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

这一节看似很轻松的把作用域链引出来,并讲完了。之所有轻松是有前几节的基础,否则将很难解释。
接下来咱们开始正式说说一直期待依旧的朋友——闭包。敬请期待下一节。

深入理解javascript原型和闭包(14)——从【自由变量】到【作用域链】相关推荐

  1. 深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】

    撸了今年阿里.头条和美团的面试,我有一个重要发现.......>>> 上文简单介绍了作用域,本文把作用域和上下文环境结合起来说一下,会理解的更深一些. 如上图,我们在上文中已经介绍了 ...

  2. 深入理解javascript原型和闭包(16)——完结

    之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就"不容易学".不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学java ...

  3. 深入理解javascript原型和闭包(17)——补this

    本文对<深入理解javascript原型和闭包(10)--this>一篇进行补充,原文链接:http://www.cnblogs.com/wangfupeng1988/p/3988422. ...

  4. 深入理解javascript原型和闭包(3)——prototype原型

    既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...

  5. 深入理解javascript原型和闭包(2)——函数和对象的关系

    上文(理解javascript原型和作用域系列(1)--一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...

  6. 深入理解javascript原型和闭包

    原文链接http://www.cnblogs.com/wangfupeng1988/p/3977924.html 对象是属性的集合. function show(x) {console.log(typ ...

  7. 深入理解JavaScript原型与闭包

    说明 本文为作者学习记录相关笔记及理解,如有不妥之处,请各位读者积极指出, 虽然标题是深入理解,但可能存在许多不够深入的地方,请各位小伙伴不吝赐教 一切都是对象 一切引用类型都是对象,对象是属性的集合 ...

  8. 深入理解javascript原型和闭包(15)——闭包

    前面提到的上下文环境和作用域的知识,除了了解这些知识之外,还是理解闭包的基础. 至于"闭包"这个词的概念的文字描述,确实不好解释,我看过很多遍,但是现在还是记不住. 但是你只需要知 ...

  9. 深入理解javascript原型和闭包(11)——执行上下文栈

    继续上文的内容. 执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境.当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境.处于活动状态的执行 ...

最新文章

  1. SQL Server 远程无法连接
  2. 山寨c 标准库中的getline 函数
  3. 项目范围管理——知识要点
  4. ASP.NET Core中如何调整HTTP请求大小的几种方式
  5. Kali Linux 2019.4用U盘安装以及解决Kali Linux 2019.4中文乱码问题
  6. PowerDesigner(一)-PowerDesigner概述(系统分析与建模)
  7. java mysql 分页计算公式_关于Java的分页算法,急!
  8. Android基于腾讯云的小直播开发步骤
  9. oppo(不root)手机查看万能钥匙破解的wifi密码实例
  10. 编码浅析 ASCII EASCII GBK系列 Uincode UTF-8/16/32
  11. 哈工大车万翔教授:NLPer的核心竞争力是什么?
  12. eplan如何导入access_EPLAN导入edz文件太慢如何解决
  13. 5000元档投影仪挑选指南,当贝F3与极米H3两款旗舰级投影到底怎么选?
  14. Python练习猜拳,利用while循环自定义函数,结果数据存入excel表格
  15. 【融职教育】Web全栈开发就业班核心优势
  16. Sai Life Sciences任命COO;Affamed 在华植入首例景深延长型人工晶状体 | 医药健闻
  17. 如何规划与实施数字化工厂?
  18. 翻译: Deep Convolutional Neural Networks for Breast Cancer Histology Image Analysis
  19. 慕课网的python2020_2020中.国大学慕课Python开发入门答案
  20. OPPO折叠屏发布后,外媒把“矛头”对准三星,Find N和Fold 3哪个好?

热门文章

  1. T-SQL中的GROUP BY GROUPING SETS
  2. kafka安装及Kafka-PHP扩展的使用
  3. 详谈PHP垃圾回收机制
  4. 反思自己钻牛角尖:间隔反思思维方法 时时刻刻反馈目标
  5. Linux的find -print 和 -print0区别:换行不换行
  6. Linux的Nginx四:功能|模块
  7. 日期时间选择器-jeDate日期控件
  8. sap 一代增强_在SAP标准实施中不起眼的“小”功能,居然融了3个亿
  9. 中文表示什么_越南水果摊贴出中文标语,看清文字内容后,中国游客:不再吃了...
  10. 3pc在mysql的实现_面试官:了解分布式事务?讲讲你理解的2PC和3PC原理