你不知道的javascript:作用域,编译器,js引擎的关系

一,作用域概念:

我的理解是:js引擎或编译器对变量的操作可以起作用的一块空间,脱离了这个空间,变量就“无效”了。 专业的解释是:作用域是
根据名称查找变量的一套规则。(现实中,通常需要同时顾及几个作用域)

二,常规的编译过程:三步:对 var a =2;的编译步骤
> 1,分词/词法分析:将字符串分解成代码块,又称词法单元。var 、a、=、2、;

2,解析/语法解析:词法单元流(数组)生成AST抽象语法树
3,代码生成:将AST转换成可执行的代码。(将AST转化为一组机器指令,用来创建一个叫做a的变量,包括内存分配,并将一个值2存储在a中)。

三,相比上述编译器的的三步编译,javascript的引擎更复杂,例如,他会在第二三步骤对 运行性能 进行优化,包括对冗余元素进行优化。

四,js的编译
遇到 var a =2; 引擎认为这里有两个不同的声明。一个由编译器在编译时处理,一个由js引擎在运行时处理。

1,遇到 var a,编译器会询问作用域,是否已经有一个该名称的变量在同一个作用域的集合中。如果是,编译器忽略该声明,继续进行编译。否则,他会要求作用域在该集合中声明一个变量,命名为a。
2,接下来,编译器会为引擎生成运行时所需的代码,这些代码被用来处理a = 2
这个赋值操作,引擎会问作用域,在当前的作用域集合中是否有a这个变量,如果有引擎就拿来用,如果否,引擎会继续查找该变量。如果引擎找到了变量a,就会将2赋值给他,否则引擎就会抛出一个异常!

说白了,一个声明变量,一个拿来使用,中间,两者都要让作用域参与。

五,LHS 和 RHS ,

是一个赋值操作的左侧和右侧。L是查询和赋值 R是查询(取到他的源值)

六,ReferenceError ,TypeError
ReferenceError 对象代表当一个不存在的变量被引用时发生的错误.

当执行RHS引用时,如果对变量使用了错误的用法,比如对一个未声明过的变量a执行函数操作a(),报错ReferenceError。对未声明过的变量a执行访问操作(害,RHS不就是查询引用操作吗),a,报错ReferenceError。

如果对null或者undefined的变量(声明过了,未赋值或置为null)进行属性访问 a.xxx的操作,报错TypeError。

总结:只要声明过了,再进行不合理的操作,基本就是TypeError。只要没声明过,再进行不合理
的操作,就是引用错误ReferenceError。

当执行RHS时,被执行的代码变量不一定有作用域,可能还没有被声明过,所以,会出现个ReferenceError 和 TypeError错误。
当执行LHS时,如果变量没有被声明过,引擎会声明一个同名的变量(前提是在非严格模式下,严格模式下,LHS的变量声明会被阻止,所以,我们自己测试时,可以适当的调整环境模式:严格模式、慵懒模式、)

七八九十

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值