javascript基础学习系列三十四:作用域链增强

本文讨论了JavaScript中执行上下文的两种主要类型,以及with语句如何在作用域链前端添加临时上下文。着重比较了var与let在函数作用域和块级作用域中的行为差异,以及ES6引入的新变量声明方式。
摘要由CSDN通过智能技术生成

虽然执行上下文主要有全局上下文和函数上下文两种(eval()调用内部存在第三种上下文),但有 其他方式来增强作用域链。某些语句会导致在作用域链前端临时添加一个上下文,这个上下文在代码执 行后会被删除。通常在两种情况下会出现这个现象,即代码执行到下面任意一种情况时:

  • try/catch 语句的 catch 块
  • with 语句
    这两种情况下,都会在作用域链前端添加一个变量对象。对 with 语句来说,会向作用域链前端添
    加指定的对象;对 catch 语句而言,则会创建一个新的变量对象,这个变量对象会包含要抛出的错误 对象的声明。
function buildUrl() {
      let qs = "?debug=true";
      with(location){
        let url = href + qs;
}
return url; }

with 语句将 location 对象作为上下文,因此 location 会被添加到作用域链前端。 buildUrl()函数中定义了一个变量 qs。当 with 语句中的代码引用变量 href 时,实际上引用的是 location.href,也就是自己变量对象的属性。在引用 qs 时,引用的则是定义在 buildUrl()中的那 个变量,它定义在函数上下文的变量对象上。

而在 with 语句中使用 var 声明的变量 url 会成为函数 上下文的一部分,可以作为函数的值被返回;但像这里使用let声明的变量url,因为被限制在块级作 用域(稍后介绍),所以在 with 块之外没有定义。

1. 变量声明:

ES6 之后,JavaScript 的变量声明经历了翻天覆地的变化。直到 ECMAScript 5.1,var 都是声明变量 的唯一关键字。ES6 不仅增加了 let 和 const 两个关键字,而且还让这两个关键字压倒性地超越 var 成为首选。

(1)使用 var 的函数作用域声明

在使用 var 声明变量时,变量会被自动添加到最接近的上下文。在函数中,最接近的上下文就是函 数的局部上下文。在 with 语句中,最接近的上下文也是函数上下文。如果变量未经声明就被初始化了, 那么它就会自动被添加到全局上下文,如下面的例子所示:

   function add(num1, num2) {
      var sum = num1 + num2;
      return sum;
    }
    let result = add(10, 20); // 30
console.log(sum); // 报错:sum 在这里不是有效变量

这里,函数 add()定义了一个局部变量 sum,保存加法操作的结果。这个值作为函数的值被返回, 但变量 sum 在函数外部是访问不到的。如果省略上面例子中的关键字 var,那么 sum 在 add()被调用 之后就变成可以访问的了。

function add(num1, num2) {
      sum = num1 + num2;
return sum; }
    let result = add(10, 20); // 30
    console.log(sum);         // 30

变量 sum 被用加法操作的结果初始化时并没有使用 var 声明。在调用 add()之后,sum被添加到了全局上下文,在函数退出之后依然存在,从而在后面可以访问到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值