JS之作用域是什么(一)

JS之作用域是什么(一)

  • 由问题引出概念(什么是作用域?)

字面意思:编程语言中的变量能起作用的范围?(变量又是什么?起什么作用?)

总结书上的解释:编程语言最基本的功能之一,就是存储变量中的值,并且可以对值进行处理,正是这种处理变量的能力(储存、访问、修改值)把状态带给了程序。

问题引出: 那么这些所谓的变量存储在何处?以什么方式存储?使用某个变量时,怎么找到?

一个很简单明了的对作用域的解释: " 上述对变量所提出的问题,说明需要一套良好的规则来存储变量,并且之后可以方便的找到这些变量,那么这套规则被称为作用域 "

  • 理解作用域

引擎: 从头到尾负责整个JavaScript程序的编译及执行过程

编译器: 引擎的好朋友之一,负责语法分析及代码生成

作用域: 引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限

举个例子:

   var a = 2;  // 声明一个变量

解释声明一个变量并初始化时,三个对象的执行过程(此处分为两部分)

  1. 当编译器遇到 var a 的时候,编译器会询问作用域是否已经有一个该名称的变量存在同一个作用域的集合中。如果是编译器则会忽略此语句,继续进行编译,否则它将要求作用域在当前作用域的集合中声明一个新的变量,并命名为a。
  2. 接下来,编译器会为引擎生成运行时所需代码,这些代码用来处理 a = 2这个赋值操作。引擎运行时会首先询问作用域,在当前的作用域集合中是否存在一个叫做a的变量,如果是,引擎就会使用这个变量,如果没有引擎会继续查找,直到找到为止(1、找到了就赋值。2、找不到引擎就抛出一个异常!

总结: 变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。

关于编译器的小插曲

     编译器在编译过程的第二步中生成了代码,引擎执行它时,会通过查找变量a来判断它是否声明过,查找的过程由作用域协助,但是引擎执行怎样的查找,会影响最终的查找结果。
  • LHS查询: 对哪个赋值,就对哪个进行LHS查询,可以理解为赋值操作的目标。
    a = 2; // 这是对a进行LHS引用,不关心当前值是什么,只是想要为 =2这个赋值操作找一个目标
  • RHS查询: 需要获取哪个变量的值就对哪个变量的值进行RHS引用,理解为赋值操作的源头。
    console.log(a) // 这里就是对a的RHS引用,因为没有对a进行赋值,只是获取a的值传给console.log。
  • 作用域嵌套

提醒: 作用域是根据名称查找变量的一套规则

作用域嵌套: 当一个块代码或函数,在另一块代码或函数内部时,就形成了作用域嵌套。在当前作用域中找不到变量时,引擎就会在外层嵌套的作用域中继续查找。逐层向上。

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

在函数内部,需要进行 a b 和的计算,但是函数foo内部无 b,所以在当前函数内部作用域中无法对 b 进行RHS查询,此时引擎只能在外层查找 b 找到后引用,并将函数执行完毕。

遍历嵌套作用域链的规则: 引擎从当前的执行作用域中开始查找变量(LHS和RHS一样,在当前作用域查找)如果找不到就向上一级继续查找,当抵达最外层的全局作用域时,无论找没找到,查找过程都会终止!逐层向上!!!

  • 异常!!!

抛出心里面的一个很重要的问题: " 为什么要区分 LHS 和 RHS ?"

聊聊在遍历完所有作用域后仍没找到变量时,对于两种查询的不同情况:

  1. RHS查询:如果RHS查询在所有嵌套的作用域中遍寻不到所需变量,引擎就会抛出ReferenceError异常。
  2. LHS查询:当引擎执行LHS查询时,如果在顶层作用域还是无法找到所查找的变量,全局作用域就会自动创建一个该变量名称的变量(在非严格模式下,严格模式下不会创建一个同名全局变量,同时引擎会抛出同RHS查询失败是类似的ReferenceError异常),并将其返还给引擎。
  3. 如果试图强行对一个变量的值进行不合理的操作,比如试图将一个非函数类型的值进行函数调用,或者引用null、undefined类型的值中的属性,那么引擎就会抛出另一种类型的异常,TypeError。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值