js作用域中的那些事儿(you don‘t know javascript)

来源:互联网 发布:淘宝手机端详情页模板 编辑:程序博客网 时间:2024/05/18 16:58

在《你不知道的javascript(上)》中,了解到javascript在代码执行前会先对代码进行编译,引擎查找变量的过程中提到了LHS查询和RHS查询两个概念,下面就简单谈一下自己对其的理解:

LHS查询:在查找变量中,如果查找的目的是为了给变量赋值(“=”),就会执行LHS查询。

RHS查询:在查找变量中,如果查找的目的是为了找到该变量是啥,就会执行RHS查询。

那么什么是作用域呢,作用域是有什么决定的呢?

书中的解释是“根据名称查找变量的一套规则”,说白了就是引擎是怎么查找变量的,是在哪里,按照什么样的规则找到该变量的--从当前的执行作用域开始查找变量, 如果找不到,就向上一级继续查找。 当抵达最外层的全局作用域时, 无论找到还是没找到(代码执行就会报错), 查找过程都会停止。作用域是由书写代码时,函数(或者变量)的位置决定的。

变量提升

var a = 3;

JavaScript 引擎首先会在代码执行前对其进行编译, 在这个过程中, 像 以上这样的声明会被分解成两个独立的步骤:变量的声明和对变量进行赋值

变量声明:在作用域中声明变量var a;这个过程会发生在代码(一切的处理逻辑)执行之前(最前面),也就是传说中的变量提升;

变量赋值:a=3是在代码执行的过程中进行的(LHS查询,因为这是一个赋值的过程,会查询变量a并对其进行赋值);

例如:下面的代码会报错:

function foo(a) {    console.log(a + b);    b = a;}foo(2);
因为在执行console的时候会查找b,但是找不到因为根本就没有声明该变量;所以...,再看下面的例子:

function foo(a) {    console.log(a + b);   var  b = a;}foo(2);

这个结果会返回NaN,这个例子和上面的例子唯一的不同就是 b =  a变成了 var b = a;虽然只是前面多了一个var,但是正式这个 var b = a;引擎解析的时候是分成了两部分var b(在执行console之前会执行)和b=a;RHS查询的时候找到了该变量,但是还是不知道这个变量是啥(LHS查询失败);

注:其实 "a is not defined"和undefined是不一样的错误,前者是在全局作用域中都没有找到a这个变量,才报的错误;后者是找到该变量了,但是没有找到该变量的值(RHS查询,相当于var a;)