【动画演示】:JS 作用域链不在话下
作者:Lydia Hallie
译者:前端小智
来源:dev
点赞再看,养成习惯
本文
GitHub
https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
本篇我们来看看啥是作用域以及作用域链,首先,来看看下面的代码:
const name = "Lydia"
const age = 21
const city = "San Francisco"
function getPersonInfo() {
const name = "Sarah"
const age = 22
return `${name} is ${age} and lives in ${city}`
}
console.log(getPersonInfo())
// Sarah is 22 and lives in San Francisco
我们调用getPersonInfo
函数,它返回一个包含姓名、年龄和城市变量值的字符串:Sarah is 22 and lives in San Francisco
。但是,getPersonInfo
函数中不包含变量 city
,它是怎么取到 city
的值?
首先,JS 引擎为不同的上下文设置内存空间。我们有默认的全局上下文(浏览器中的window
、Node 中的global
),以及已经调用的getPersonInfo
函数的本地上下文,每个上下文还有一个作用域链。
对于getPersonInfo
函数,作用域链看起来是这样的:
作用域链基本上是对对象的“引用链”,其中包含对在执行上下文中可引用的值(和其他作用域)的引用。作用域是在创建执行上下文时创建的,这说明它是在运行时创建的。
在本文中,不会讨论激活对象或执行上下文,我们只关注作用域。 在以下示例中,执行上下文中的键/值对表示使作用域链对变量的引用。
全局执行上下文(GLOBAL EXECUTION CONTEXT)的作用域链引用了3
个变量:值为Lydia
的name
、值为21
的age
和值为San Francisco
的city
。在本地执行上下文(LOCAL EXECUTION CONTEXT)中,我们引用了两个变量:name
值为Sarah
, age
值为22
。
当我们试图访问getPersonInfo
函数中的变量时,JS引擎首先检查局部作用域链。
本地作用域链有一个name
和age
的引用!name的值是Sarah, age的值是22。但是现在,当它试图访问city
变量时会发生什么?
为了找到变量city
的值,JS 引擎沿着作用域链向上查找,直到在外部作用域内为找到了一个city
的值,本地作用域有一个引用,在本例中是全局对象。
在全局上下文中,我们用San Francisco
的值声明了变量city
,因此有一个对变量city
的引用。现在我们有了变量的值,函数getPersonInfo
可以返回字符串Sarah is 22 and lives in San Francisco
。
我们可以沿着作用域链向下走,但是我们不能沿着作用链向上走,这可能会让人困惑,因为我们大都会说“向上”而不是“向下”,所以换一种说法:你可以进入外部作用域,但不能进入内部作用域,可以把它想象成瀑布模型:
更深的嵌套:
以这段代码为例:
这个跟上个例子代码几乎是一样的,但是有一个很大的区别:我们现在只在getPersonInfo
函数中声明city
,而不在全局作用域中。这里也没有调用getPersonInfo
函数,所以也没有创建本地上下文。然而,我们试图在全局上下文中访问name
、age
和city
的值。
这里分抛出一个ReferenceError
异常,因为 JS 在全局范围内找不到一个名为city
的变量的引用,因为已处于顶部作用域,也没法向上的作用域查找了。
通过这种方式,我们可以将作用域用作“保护”变量并重新使用变量名的方法。
除了全局作用域和局部作用域之外,还有一个块作用域。使用let
或const
关键字声明的变量的作用域就是块作用域。
const age = 21
function checkAge() {
if (age < 21) {
const message = "You cannot drink!"
return message
} else {
const message = "You can drink!"
return message
}
}
可以将上面的作用域可视化为:
这里有一个全局作用域、一个函数作用域和两个块作用域。我们可以两次声明变量message
,因为message 变量处在不同的作用域中。
快速回顾:
- 可以将“作用域链”看作是在当前上下文中访问的值的引用链。
- 作用域还可以重用在该该作用域链上定义的变量名,因为它会沿着作用域链向上查找。
原文:https://dev.to/lydiahallie/ja...
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
交流
干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
https://github.com/qq44924588...
我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,即可看到福利,你懂的。
【动画演示】:JS 作用域链不在话下的更多相关文章
- js作用域链
js作用域链 <script> var up = 555; function display(){ var innerVar = 2; function inner(){ var inne ...
- Js作用域链及变量作用域
要理解变量的作用域范围就得先理解作用域链 用var关键字声明一个变量时,就是为该变量所在的对象添加了一个属性. 作用域链:由于js的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是 ...
- [js]作用域链查找规则获取值和设置值
作用域链查找规则获取值和设置值 <script> /** 1.作用域链查找规则 私有作用域出现的一个变量不是私有的,则往上一级作用域查找,上级作用域没有则继续向上级查找,一直找到windo ...
- js 作用域链&内存回收&变量&闭包
闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等 一.作用域链:函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内部的规则是,把函数自身的本地变量放在 ...
- js作用域链和预编译
js引擎运行分为两步,预解析 代码执行 (1)预解析: js引擎会拿js里面所有的var还有 function 提升到当前作用域的最前面 (2)代码执行:按照代码书写的顺序从上往下执行 预解析分为:变 ...
- js作用域链以及全局变量和局部变量
> [带var] > 在当前作用于中声明了一个变量,如果当前是全局作用域,也相当于给全局作用域设置了一个属性叫做a ```javascript //=>变量提升:var a; < ...
- 关于js作用域链,以及闭包中的坑
eg:链式作用域,想在外部读取blogName的值得方法 <script>var authorName="山边小溪";function doSomething(){ ...
- js作用域链与this
this的绑定与function和对象的定义位置无关,是由函数调用时的执行环境所决定的. scope chain是由函数定义时的位置决定的与函数调用时的执行环境无关.
- 前端知识体系:JavaScript基础-作用域和闭包-JavaScript的作用域和作用域链
JavaScript的作用域和作用域链 作用域: 变量的作用域无非两种:全局作用域和局部作用域 全局作用域: 最外层函数定义的变量拥有全局作用域.即对任何内部函数来说都是可以访问的. <scri ...
随机推荐
- Laravel Vuejs 实战:开发知乎 (2)用户登录
1.安装一个给用户提示的扩展包: 二选一: https://github.com/laracasts/flash [我选的这个]https://github.com/oanhnn/laravel-fl ...
- Numpy Pandas
数据分析 : 是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律. 数据分析三剑客 - Numpy Pandas Matplotlib # Numpy 基于一维或多维的数 ...
- python编程出现:expected an indented block错误。
python编程出现:expected an indented block错误. expected an indented block翻译为:应为缩进块. python中没有像C语言使用{}来表示从属 ...
- Python分析盘点2019全球流行音乐:是哪些歌曲榜单占领了我们?
写在前面:圣诞刚过,弥留者节日气息的大家是否还在继续学习呐~在匆忙之际也不忘给自己找几首好听的歌曲放松一下,缠绕着音乐一起来看看关于2019年流行音乐趋势是如何用Python分析的吧! 昨天下午没事儿 ...
- Python - int()
参考 https://docs.python.org/3/library/functions.html?highlight=int#int If x is not a number or if bas ...
- 关于umask的计算方式(简单任性)
1.对于文件夹[d]来说 用755-umask 3.对与文件[f]来说,在2的基础上减掉x属性就完事儿(有x的,减掉1,没有的,就什么也不管) 再来个手绘版本的举例
- 关于idea2019.2.3版本中文控制台乱码问题
出现乱码后根据网上找的方法全都试过后还是显示乱码 更改VM Options为 -Dfile.encoding=UTF-8 添加备选字体 更改这两个文件 更改编码格式 以上这些方法全部设置 ...
- Python os模块、os.path模块常用方法
os模块:os模块在python中包含普遍的操作系统功能,下面列出了一些在os模块中比较有用的部分. os.sep 可以取代操作系统特定的路径分隔符.windows下为 "\" o ...
- SVM的优缺点
优点 可用于线性/非线性分类,也可以用于回归,泛化错误率低,也就是说具有良好的学习能力,且学到的结果具有很好的推广性. 可以解决小样本情况下的机器学习问题,可以解决高维问题,可以避免神经网络结构选择和 ...
- P1893山峰瞭望
传送门 看完这个题,大家都懂意思吧,然后代码呢,emmmmm #include <bits/stdc++.h> using namespace std; const int maxn = ...