之前看过 《You don't know js》中说到的 LHS ,RHS.
然而还是对这个知识点懵懵懂懂 , 了解粗浅。
碰到这种题目一时间还是无法理解:
var foo = { n: 1 };
var bar = foo;
foo.x = foo = { n: 2 };
console.log(foo.x) // ?
console.log(bar.x) // ?
在这之前先简单说一下前提概念:
简述编译原理
JavaScript 程序中的一段源代码在执行之前会经历三个步骤,统称为 编译
1. 分词/词法分析
2. 解析/语法分析
3. 代码生成
先看原书对一个赋值操作的拆解说明:
变量的赋值操作会执行两个动作,
首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),
然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。
而要讲的 LHS 和 RHS 就是上面说的对变量的两种查找操作,查找的过程是由作用域(词法作用域)进行协助,在编译的第二步中执行。
LHS 和 RHS
字面意思其实是 Left Hand Side和 Right Hand Side 即左手边和右手边
一般可以理解为 赋值操作的左侧和右侧
但更准确来说,
LHS 是 查找变量的 内存地址 (类似于C语言中的变量对应的指针值)
RHS 是 查询变量的 值.
先举个最简单的例子:
var a=1;
从这里 发生了一次 LHS 引用: var a...
,获取 a 的变量地址,然后把 1 赋值给 a.
再来一个:
console.log(a);
显然 , 为了打印 变量 a 的值 , 这里需要获取到 a的具体值 , 发生了 RHS
延伸到函数:
function sayHi(name){
console.log(name);
}
sayHi('小明');
第一步,这里 sayHi ('小明')
,其中 sayHi...
调用了RHS,获取这个函数的内容.
第二步,括号里面进行了一次传参,也就是 name = 小明
, 发生了一次LHS,把 小明
赋值给 name
第三步, console.log(..)
本身也需要一个 RHS 引用,即对 console 对象进行 RHS 查询,并且检查得到的值中是否有一个叫做 log 的方法。
第四步, console.log(name)
, 为了获取到 name
具体的值 发生RHS ,
总结就是 , 执行 sayHi('小明')
这个过程中 ,一共发生了 一次LHS,三次RHS。
可以来道小题练练手:
试试找出其中的3处 LHS 查询,4处 RHS 查询
function foo(a) {
var b = a;
return a + b;
}
var c = foo(2);
答案:
LHS 查询
c = ..;
a = 2(隐式变量分配)
b = ..
RHS 查询
foo(2..
= a;
a ..
.. b
重新做题
接下来回到文中开头的题目:
var foo = { n: 1 };
var bar = foo;
foo.x = foo = { n: 2 };
console.log(foo.x) // ?
console.log(bar.x) // ?
详细解析可以参考
https://juejin.im/entry/5acb0dc55188255c5668bbe2?utm_source=gold_browser_extension