JavaScript作用域深入

编译相关

一般源代码编译步骤:分词/词法分析:代码分解为词法单元 => 解析/语法分析:将词法单元数组构建为抽象语法树 => 代码生成:将抽象语法树转换为可执行代码

两种查询类型:LHS和RHS,赋值号左边和赋值号右边的区别

a = b
对于a来说,编译器执行的是LHS查询,即获取变量a的容器(也就是地址),要写这个变量

对于b,执行RHS查询,获取变量b的值,要读这个变量

不管是LHS查询还是RHS查询,如果在当前作用域没有查到变量,会不断到外层作用域进行查询,直到全局作用域。

RHS直到全局作用域任未查询到的话会抛出ReferenceError

而对于LHS,如果在全局作用域没有找到的话,会在全局作用域中创建一个该变量,所以就会出现这种情况

function foo(a){
    console.log(a)
    b = a
}
foo(2)
console.log(b) // 打印2 且不会报错

作用域欺骗

eval和with会对作用域产生奇奇怪怪的影响,且会导致引擎无法进行优化,严重影响效率,禁止使用

函数作用域和块作用域

函数表达式、立即执行函数表达式

函数表达式

setTimeout(function(){
    // todo
},1000)

立即执行函数表达式

(function(a){
    console.log(a);
})(a)

块作用域

三种类型:

  • 选择循环流程块,类似for,if块
  • try catch块
  • {}块

对于 var修饰的变量,实际作用域会跳出当前块作用域(并不会跳出函数作用域),所以才有了let和const,会被限制在块作用域中

function foo(a){
        if(a){
            var b=2
        }
        console.log(b) // 能够得到2,因为var定义的b会跳出块作用域
}
foo(true)
console.log(b) //ReferenceError 跳不出函数作用域
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值