JS 执行环节与作用域(十五)

执行环境(环境)定义了变量或函数有权访问的其他数据。每个执行环境都有一个与之关联的变量对象,环境变量中定义的所有变量和函数都保存在这个对象中。

环境:

  • 全局环境,是最外围的一个执行环境,在Web浏览器中,全局执行环境被认为是window对象。
  • 局部环境,函数内部的执行环境,当执行流进入一个函数时,函数的环境就会入环境栈,当函数执行完成后就会将环境弹出。

作用域链
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终是当前执行的代码所在的环境的变量对象。如果该环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,在arguments对象。下一个变量对象来自包含(外部)环境,再下一个变量对象则来自下一个包含环境,以此类推知道全局执行环境。

标识符解析是沿着作用域链一级一级搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级向后回溯,直到找到标识符(通常找不到就会出错)


内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中任何变量和函数。

延长作用域链

  • try-catch语句的catch
  • with语句

上述两个语句都会在作用域链的前端添加一个变量对象。对于with语句,会将指定的对象添加到作用域链中。对于catch语句,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

function buildUrl() {
     var qs = "xxxx"
     with(location) {
         var url = href + qs
     }
     return url
}

上述代码中,with语句接收的是location对象,因此其变量对象中包含了location对象的所有属性和方法,并且该变量对象被添加到了作用域链的前端。

没有块级作用域
在JS中没有块级作用域

if(true) {
     var color = 'blue'
}
alert(color) // 'blue'
for(var i = 0; i < 10; i++)    {
     doShomething(i)
}
alert(i) // 10

如上述两个例子,JS没有函数作用域,使用let声明变量可以避免该问题。使用var声明的变量会自动被添加到最接近的环境中。

查询标识符
当在某个环境中为了读取或写入而引用一个标识符时,必须通过搜索来确定该标识符实际代表什么。搜索过程是从作用域链的前端开始的,向上级查询与给定名字匹配的标识符。如果在局部环境中找到了就停止,如果没找到就继续向上级全局环境搜索。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值