记一条关于 js 左右引用(LHS RHS )的题目

之前看过 《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

你可能感兴趣的:(记一条关于 js 左右引用(LHS RHS )的题目)