谈谈 JavaScript 的作用域及作用域链
前言
作用域和作用域链在前端里是比较简单的概念,但往往因为简单而被人忽视,涉及到作用域链产生的 bug 很容易让人摸不着头脑。其实再简单的知识点也有复杂的地方,就像再复杂的概念也有易于理解的点一样。今天大冰块从 作用域 , 变量范围 , 作用域链 这三个方面好好谈一谈 JavaScript 的作用域及作用域链,希望各位同学看完之后能有所收获。
作用域
概念:变量声明后,能够在哪个范围内起作用。
块级作用域
块级作用域: 由花括号组成代码结构的范围 {}
,在花括号里面声明的变量在外部无法访问。其实 JavaScript 是不支持块级作用域的,那么为什么大冰块还要说一下这个呢?多了解一点总是没坏处的,比如面试的时候,别人没说这个,但是你把这个点一提,是不是水平立马就提升了?(手动滑稽)
词法作用域
词法作用域: 也叫函数作用域,因为在 js 里面,只有函数才能形成作用域。也叫静态作用域,因为它的作用域是指在词法分析阶段就确定了,不会改变。动态作用域是在运行时根据程序的流程信息来动态确定的,而不是在写代码时进行静态确定的。而词法作用域是在写代码或者定义时确定的,而动态作用域是在运行时确定的(this 也是!)。词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。
变量范围
根据作用域把变量分为 3 类
全局变量
在函数外部声明的变量就是全局变量,在任意位置都能够访问到
局部变量
在函数内部声明的变量就是局部变量,只能在函数内部使用。
自由变量
对于一个函数来说,如果这个变量不是在这个函数内部声明的,但是却使用了这个变量,对于这个函数来说,这个变量就是自由变量
作用域和变量的关系
函数的作用域在函数定义的时候就已经确定下来了,函数定义的时候就已经确定下来了,函数定义的时候就已经确定下来了,重要事情说三遍。也就是说,函数作用域和函数在哪调用是没有关系的,以及函数如何被调用都是没有关系的。和 this 不同,this 是在函数被调用的时候才确定,函数是如何被调用的。函数作用域的查找是如何查找到呢?
好了,说了这么多,出一道题考考你,请看下面的题目:
各位同学,请把你的答案贴在评论区。
作用域链
作用域链:函数能够形成作用域,如果函数被嵌套在另一个函数中,嵌套的函数也有自己的作用域,从这个函数的作用域往外形成的一条链, 这个链叫做作用域链。例如:
上面代码中:函数 outer 的作用域链: outer 作用域 ==> 全局作用域函数 inner 的作用域链: inner 作用域 ==> outer 作用域 ==> 全局作用域 fn 的作用域链: fn 作用域 ==> inner 作用域 ==> outer 作用域 ==> 全局作用域
作用域链: 变量搜索规则:
好了,下面再出一道题考考大家:
各位同学,请把再次把你的答案贴在评论区。
后记
在平时写代码的过程中,如果作用域和作用域链如果理解的不透彻,很容易产生 bug。相信通过大冰块从作用域,变量范围,作用域链这几个方面的详细解读,你一定对作用域和作用域链有了更透彻的理解。如果本篇文章由帮助到你,希望能点赞支持一下,不枉我熬夜淦完这篇文章。如果有错误也欢迎指出交流。感谢阅读~
版权声明: 本文为 InfoQ 作者【南极一块修炼千年的大冰块】的原创文章。
原文链接:【http://xie.infoq.cn/article/882f93be9f4a9799097c749a1】。文章转载请联系作者。
评论