前言
系列首发于公众号『前端进阶圈』,若不想错过更多精彩内容,请“星标”一下,敬请关注公众号最新消息。
前言
- 在上篇文章中, 咱们说了作用域一共分为两种:
词法作用域
和动静作用域
,而这篇文章咱们一起来学习动静作用域
。
动静作用域
- 动静作用域仿佛有着很好的理由让作用域作为一个在运行时就被动静确定的模式,而不是在写代码时进行动态确定的模式。
-
考虑一下代码:
function foo() {console.log(a); // 2 } function bar() { var a = 3; foo();} var a = 2; bar();
- 在上述代码中,词法作用域让 foo() 中的 a 通过 RHS 援用到了全局作用域中的 a, 因而输入 2;
在动静作用域中,它并不关怀函数和作用域是如何申明以及在何处申明的,只关怀他们从何处调用的
。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套的。
- 如果 JavaScript 具备动静作用域,实践上,上述代码 foo() 中的 a 输入 3; 因为 foo() 是在 bar() 中调用的,
-
为什么会这样?
- 因为当 foo() 无奈找到 a 的变量援用是,会顺着调用栈在调用 foo() 的中央查找 a,而不是在嵌套的词法作用域链中向上查找。因为 foo() 是在 bar() 中调用的,引擎会查看 bar() 的作用域,并找到值为 3 的变量 a。
-
是不是很奇怪?
- 但这其实是因为你可能只写过基于词法作用域的代码,因而对动静作用域感到生疏。如果你只用基于动静作用域的语言写过代码,就会感觉很天然的,而词法作用域看上去才怪怪的。
事实上 JavaScript 并不具备动静作用域,它只有词法作用域
。但 this 机制的存在在某种程度上很像动静作用域。
词法作用域与动静作用域的区别?
- 动静作用域其实是 JavaScript 另一个重要机制 this 的表亲
- 词法作用域是在书写代码或定义时确定的
- 动静作用域是在运行时确定的。(this 也是)
- 词法作用域关注函数在何处申明
- 动静作用域关注函数从何处调用
- 其实在 JavaScript 中的作用域大多为词法作用域。
- 作用域链是基于调用栈的,而不是代码中的作用域嵌套的
特殊字符形容:
- 问题标注
Q:(question)
- 答案标注
R:(result)
- 注意事项规范:
A:(attention matters)
- 详情形容标注:
D:(detail info)
- 总结标注:
S:(summary)
- 剖析标注:
Ana:(analysis)
-
提醒标注:
T:(tips)
往期举荐:
- 前端面试实录 HTML 篇
- 前端面试实录 CSS 篇
- JS 如何判断一个元素是否在可视区域内?
- Vue2、3 生命周期及作用?
- 排序算法:QuickSort
- 箭头函数与一般函数的区别?
- 这是你了解的 CSS 选择器权重吗?
- JS 中 call, apply, bind 概念、用法、区别及实现?
- 罕用位运算办法?
- Vue 数据监听 Object.definedProperty()办法的实现
- 为什么 0.1+ 0.2 != 0.3,如何让其相等?
- 聊聊对 this 的了解?
-
JavaScript 为什么要进行变量晋升,它导致了什么问题?
最初:
- 欢送关注『前端进阶圈』公众号,一起摸索学习前端技术 ……
- 公众号回复 加群 或 扫码, 即可退出前端交流学习群,一起高兴摸鱼和学习 ……
- 公众号回复 加好友,即可添加为好友