JS引擎的LHS查询和RHS查询

270 阅读2分钟

RHS查询:与简单地查找某个变量的值别无二致,也就是得到某某的

LHS查询:试图找到变量的容器本身,从而可以对其赋值。

个人的理解是:对于一个变量 var a = 10来说。 RHS查询是找到10这个值,而LHS查询是找到a这个存放10的容器

下面是具体摘录自你不知道的javascript中的例子,分析了更具体的情况。

function foo(a) {
    console.log( a ); // 2
}
foo( 2 ); //

最后一行 foo(..) 函数的调用需要对 foo 进行 RHS 引用,意味着“去找到 foo 的值,并把 它给我”。并且 (..) 意味着 foo 的值需要被执行,因此它最好真的是一个函数类型的值!

这里还有一个容易被忽略却非常重要的细节。 代码中隐式的 a=2 操作可能很容易被你忽略掉。这个操作发生在 2 被当作参数传递给 foo(..) 函数时,2 会被分配给参数 a。为了给参数 a(隐式地)分配值,需要进行一次 LHS 查询

这里还有对 a 进行的 RHS 引用,并且将得到的值传给了 console.log(..)。console. log(..) 本身也需要一个引用才能执行,因此会对 console 对象进行 RHS 查询,并且检查 得到的值中是否有一个叫作 log 的方法。

最后,在概念上可以理解为在 LHS 和 RHS 之间通过对值 2 进行交互来将其传递进 log(..) (通过变量 a 的 RHS 查询)。假设在 log(..) 函数的原生实现中它可以接受参数,在将 2 赋 值给其中第一个(也许叫作 arg1)参数之前,这个参数需要进行 LHS 引用查询

你可能会倾向于将函数声明 function foo(a) {... 概念化为普通的变量声明 和赋值,比如 var foo、foo = function(a) {...。如果这样理解的话,这 个函数声明将需要进行 LHS 查询。

然而还有一个重要的细微差别,编译器可以在代码生成的同时处理声明和值 的定义,比如在引擎执行代码时,并不会有线程专门用来将一个函数值“分 配给”foo。因此,将函数声明理解成前面讨论的 LHS 查询和赋值的形式并 不合适。