首页 » JavaScript » 延长作用域链

延长作用域链

虽然执行环境的类型总共只有两种——全局和局部(函数),但还是有其它方法来延长作用域链。有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。当执行流进入下列任何一个语句中时,作用域链就会得到加长。

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

这两个语句都会在作用域链的前端添加一个变量对象。对with语句来说,其变量对象中包含这为指定对象的所有属性和方法所作的变量声明。对catch语句来说,其变来那个对象中包含的是被抛出的错误对象声明。这些变来那个对象都是只读的,因此在with和catch语句中声明的变来那个都会被添加到所在执行环境的变量对象中。请看下面的例子:

function buildUrl() {
    var qs = "?debug=true";
    with(location) {
        var url = href + qs;
    }
    return url;
}
var result = buildUrl();
alert(result);

在此,with语句接收的是location对象,因此其变量对象中就包含了location对象的所有属性和方法,而这个变量对象被添加到了作用域链的前端。buildUrl()函数中定义了一个变来那个qs。当在with语句中引用变量href时(实际引用的是location.href),可以在当前执行环境的变量对象中找到。当引用变量qs时,引用的则是在buildUrl()中定义的那个变量,而该变量对于函数环境的变量对象中。至于with语句内部,则定义了一个名为url的变量。由于with语句的变量对象是只读的,结果url就成了函数执行环境的一部分,因而可以作为函数的值被返回。

在IE8及之前的版本的JavaScript实现中,存在一个与标准不一致的地方,即在catch语句中捕获的错误对象会被添加到执行环境的变量对象,而不是catch语句的变量对象中。换句话说,即使在catch块的外部也可以访问到错误对象。IE9修复了这个问题。

此文章发表在 JavaScript. 将 固定链接 加入收藏.