Javascript中作用域的详细介绍(2)

  第一次对b进行RHS查询时,在任何作用域无法找到该变量的声明。那么有小伙伴就疑惑了,b=a呢?不是对b的声明吗?答案是:是。这里确实是对b的声明。
   但在对作用域查找的过程中,只会向上查找声明(涉及到声明提升)。由于这里b是在console.log()后面定义的。所以是失败的,抛出ReferenceError异常。值得注意的是,ReferenceError是非常重要的异常类型。再考虑下述代码:

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

  这里呢,第一次对b进行的是LHS查询。如果在顶层(全局)作用域也无法查到foo的话,那么Js引擎就会很热心的帮你在全局作用域创建一个b变量,前提是在非“严格模式”下,在一个作用域内加上代码“use strict”,表明使用严格模式。在严格模式下,LHS查询失败时,并不会创建一个全局变量,而是抛出同RHS查询失败时类似的ReferenceError异常。   
  接下来,加入你找到了这个变量,但是你试图对这个变量进行不合理的操作。如:对一个非函数类型的变量进行()函数调用、对null或undefined类型的值进行访问,那么引擎会抛出另一种类型的异常,叫做TypeError。   
  总之,RefercenError同作用域判别失败相关,而TypeError表示作用域判别成功,但是对结果的操作是不合法的。

5、小结

  作用域是一套规则,规定在何处以及如何查找变量(加上之前说的,重要的事情说三遍)。如果查找的目的是赋值,就是进行LHS查询。如果目的是获取变量的值,就会进行RHS查询。   
  Js引擎会在代码执行前对其进行编译。var a = 2;,这样的操作会被分成两个步骤。   
  1.编译时, 编译器声明a变量,即var a。
  2. 运行时,对a变量进行赋值。a=2。
  LHS查询和RHS查询失败会进行不同的操作。RHS查询失败会抛出ReferenceError异常。LHS查询失败会在全局作用域创建变量(非严格模式),在严格模式下抛出ReferenceError异常。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzjysg.html