JavaScript中的变量查找

作者: 娜姐聊前端 | 来源:发表于2017-03-30 23:57 被阅读496次

众所周知,JavaScript变量是按照作用域链来进行查找的(作用域和作用域链相关知识可参看我的另一篇文章,《基于JavaScript作用域链的性能调优》), 那么,对于一个简单的赋值操作,等号左右两边变量的查找方式一样吗?让我们从一个简单例子讲起~

console.log(a);   // undefined
var a = 3;
console.log(a);   // 3

console.log(b);  // ReferenceError
b = 4;
console.log(b);  //4

1. LHS(left-hand-side左查找)和RHS(right-hand-side右查找)

概念如下:

  • LHS查询:试图找到变量容器本身,从而可以对其进行赋值
  • RHS查询:查找某个变量的值

对于一个赋值语句var a = b;,等号左侧进行LHS查询,等号右侧进行RHS查询;如果是一个普通的打印语句console.log(a),那么,查找变量a属于RHS查询。

两者的相同之处:都遵循作用域链查找

2. LHS和RHS查询区别

(1) LHS查询
当JavaScript引擎执行LHS查询时,如果在顶层作用域中无法找到目标变量,那么,就会在全局作用域中创建一个具有该名称的变量,并将其返回给引擎(非严格模式下)。

要注意,这种方式创建的全局变量,严格上来讲并不是真正的变量,而是全局对象的属性,可以通过delete操作符将其删除。但是,用var声明的全局变量,是不可以用delete操作符删除的。

参考文章首部的例子:

b = 4;
console.log(b);  // 4
delete b;
console.log(window.b); // undefined

程序中并没有声明变量b,但是由于LHS查询会自动创建未找到的目标变量,所以,打印b返回4。然后删除b,可删除成功。

如果是严格模式:

"use strict";
b = 4;
console.log(b);  

这时LHS查询将无法自动创建未声明的目标变量,所以,打印b时抛出异常:Uncaught ReferenceError: b is not defined

(2) RHS查询
当JavaScript引擎执行RHS查询时,如果在作用域链中都无法找到目标变量,那么,引擎会抛出ReferenceError异常。

参考文章首部的例子:

console.log(b);  
b = 4;

RHS查询变量b,在全局作用域中未曾找到该变量定义,于是,引擎抛出异常Uncaught ReferenceError: b is not defined

3. 小贴士

(1) 变量提升
概念:用var声明的变量,总是会被JavaScript解释器悄悄地“提升”到方法体的最顶部。

参考文首的例子:

console.log(a); 
var a = 3;

JavaScript引擎会将其解析为:

var a = undefined;
console.log(a); 
a = 3;

所以,第一次打印a时会返回undefined

(2) ReferenceError和TypeError
ReferenceError代表作用域判别失败,也就是作用域内查询变量失败。
TypeError代表作用域判别成功,但是对结果的操作是非法或者不合理的。

例如:

foo();
var foo = function () {
     console.log('a');
}

执行foo()语句时,首先RHS查找,在全局作用域中找到foo变量,值为undefined(变量提升)。
然后以函数执行方式操作foo变量,很明显,undefined并不是一个合法函数,于是引擎抛出异常:Uncaught TypeError: foo is not a function,执行失败。


微信公众号:

相关文章

  • JavaScript中的变量查找

    众所周知,JavaScript变量是按照作用域链来进行查找的(作用域和作用域链相关知识可参看我的另一篇文章,《基于...

  • 作用域链

    原文出处 JavaScript深入之作用域链 作用域链 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没...

  • Web性能优化系列:10个提升JavaScript性能的技巧

    1. 定义局部变量 当一个变量被引用的时候,JavaScript将在作用域链中的不同成员中查找这个变量。作用域链指...

  • 10个提升JavaScript性能的技巧

    1. 定义局部变量 当一个变量被引用的时候,JavaScript将在作用域链中的不同成员中查找这个变量。作用域链指...

  • JS 作用域和作用域链

    作用域 JavaScript 中的作用域是我们可以有效访问变量或函数的区域。作用域规定了如何查找变量,也就是确定当...

  • 你不知道的javascrpt[上] - 笔记

    一、javascript 编译器声明变量过程?【目录: 1.2.2】 [否]声明 -> 查找 -> 赋值 var ...

  • JavaScript 中的变量作用域

    JavaScript 中的变量作用域 JavaScript中的变量作用域被定义为函数作用域。 变量的值在定义该变量...

  • JS的基本语法--变量及类型

    1. 基本语法 声明(创建) JavaScript 变量在 JavaScript 中创建变量通常称为“声明”变量。...

  • 变量提升 & this指向

    变量提升 JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。JavaScript 中,变量可以在...

  • var与let、const的区别

    什么是变量提升?JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。JavaScript 中,变量...

网友评论

    本文标题:JavaScript中的变量查找

    本文链接:https://www.haomeiwen.com/subject/jfdpottx.html