JavaScript 引擎在查找一个变量的时候,有两种查找机制:LHS 和 RHS。
RHS 的查询是简单地查找到某个变量的值,而 LHS 则是试图找到变量的容器的本身。
一个简单的例子:当我们执行 console.log(a) 时,执行的就是 RHS ,因为这里 a 并没有赋予任何的值。相应的,需要查找并取得 a 的值,这样才能将值传递给 conso.log(..)。
而当我们执行到 a = 2 时,这里对 a 的引用就是 LHS 引用,因为实际上我们并不关心当前的值是什么,只是想要为 =2 这个赋值操作找到一个目标。
需要注意的是:
当我们执行以下代码:
function foo(a){ console.log(a); // 2 } foo(2);
这里对 foo 的调用执行了 RHS 引用,但还有一个隐式的 a = 2 的操作,这里又执行了一个 LHS 引用。
我们通常把 function foo(a){} 转变为 var foo,foo = function(){} ,如果这样理解的话,这个函数声明会执行 LHS 查询,但是在引擎执行代码的时候,并不会有线程专门用来将一个函数值“分配给”foo。所以,将函数声明理解成 赋值 的 LHS 查询的形式并不合适。
区分 LHS 和 RHS 是一件很重要的事。如果 RHS 查询在作用域链中找不到需要的变量,会抛出 ReferenceError 的异常。
function foo(a){ console.log(a + b); } foo()
以上代码会抛出异常:b is not defined
相比之下,如果JavaScript引擎执行的是 LHS 查询,如果一直到顶层的作用域(全局作用域)中都没有找到目标变量的话,它就会在全局作用域中声明一个具有目标名称的变量,并将其返回给引擎。(非严格模式下,严格模式下会禁止自动创建或隐式创建全局变量)
function foo(a){ b = a; // b = 2 } foo(2)
上面的代码执行的 LHS 查询,在非严格模式下,JavaScript 引擎在全局作用域中没有找到 b,所以它就在全局作用域中声明了一个变量 b。所以此时结果不会报错且b被赋值为2。
总结:
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,就会使用 LHS 查询;如果目的是获取变量的值,就会使用 RHS 查询。
= 操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。
LHS 和 RHS 查询都会在当前执行作用域中开始,如果有需要(当前没找到),就会向上级作用域继续查找目标标识符(作用域链)。
不成功的 RHS 会导致抛出 ReferenceError 异常。不成功的 LHS 会自动隐式在全局作用域中创建一个全局变量(非严格模式下),该变量使用 LHS 引用的目标作为标识符。(如果是严格模式下也会抛出 ReferenceError 异常)。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]