这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
LHS、RHS
TIP 👉 LHS、RHS,是引擎在执行代码的时候,查询变量的两种方式。其中L、R,分别意味着Left、Right,这个“左”、“右”,是相对于赋值操作来说的。当变量出现在赋值操作的左侧时,执行的就是LHS操作,右侧则执行RHS操作
name = 'qinliang'
在这个例子里,name变量出现在赋值操作的左侧,它就属于LHS。LHS意味着变量赋值或写入内存,它强调的是一个写入的动作,所以LHS查询查的是这个变量对应的内存空间在哪。
let myName = name
console.log(name)
在这个例子中,第一行有赋值操作,但是name在操作的右侧,所以是RHS;第二行没有赋值操作,name就可以理解为没有出现在赋值操作的左侧,这种情况下我们也认为name的查询是RHS。RHS意味着变量查找货从内存中读取,它强调的是读这个动作,查询的是变量的内容。
词法作用域和动态作用域
JS的作用域遵循的就是词法作用域模型。当面试官抛出“词法作用域”这个的时候,它指的就是你最熟悉的JS作用域。
作用域其实有两种主要的工作模型:
-
词法作用域:静态作用域。
-
动态作用域:像Bash脚本等
var name = 'qinglian'
function showName() {
console.log(name)
}
function changeName() {
var name = 'BigBear'
showName()
}
changeName(); // qinglian
- 在showName函数的函数作用域内查找是否有局部变量name
- 发现没找到,于是根据书写的位置,查找上层作用域也就是全局作用域,找到了name的值是qinglian,所以结果就是qinglian
此时它的作用域关系如下:
作用域链如下:
这里我们作用域的划分,是在书写的过程中(例子中也就是在函数定义的时候,块级作用域同理是在代码块定义的时候),根据你把它写在哪个位置来决定的。像这样划分出来的作用域,遵循的就是词法作用域模型。
那什么是动态作用域呢?
- 在showName函数的函数作用域内查找是否有局部变量name
- 发现没找到,于是沿着函数调用栈、在调用了showName的地方继续找name。刚好,changeName里又一个name,于是这个name就会被引用到showName里去。
它的作用链关系如下:
如果是动态作用域,那么这段代码运行的结果就是‘BigBear’
修改词法作用域
-
with
-
eval
注意⚠️:开发过程中不要用with和eval写代码。