JavaScript 既然是通过作用域链传导编译的,那么如何延长作用域链?

这是因为有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。具体来说,就是当执行流进入下列任何一个语句时,作用域链就会得到加长:
    □:try-catch语句的catch块
    □:with语句
这两个语句都会在作用域链的前端添加一个变量对象。对with来说,会将指定的对象添加到作用域链中。对catch语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

For example:

function buildUrl() {
    var qs = "?debug=true"
    with(location) {
        var url = href + qs;
    }
    return url;
}
const aaa = buildUrl();
console.log(aaa);
//    file:///C:/Users/Administrator/Desktop/aaa.html?debug=true

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