执行环境的类型有两种:全局执行环境和局部执行环境(函数执行环境)。
1.全局执行环境的变量对象是window对象,是JS代码开始运行时的默认环境。全局执行环境的变量对象始终都是作用域链中的最后一个对象。但是还是有其他办法来延长作用域链。
2.函数执行环境,当某个函数被调用的时候,会先创建一个执行环境及其相应的作用域链,然后使用arguments对象和其他命名参数的值来初始化执行环境的变量对象。
有些语句可以在作用域前端临时增加一个变量对象,该变量对象会在代码执行之后被移除。
两种情况
1.with语句
2.try-catch语句的catch块
当执行流进入上面的任何一个语句时,作用域链就会被加长。
with语句
1.with语句的作用是将代码的作用域设置到一个特定的对象中。目的主要是为了简化多次编写同一个对象的工作。
2.使用with语句可以关联location对象,也就是说,在with语句的代码块内部,每个变量首先会被认为是一个局部变量,而如果在局部环境中找不到该变量的定义,则会查询location对象中是否有同名的属性。如果发现了同名的属性,则以location对象属性的值作为变量的值。
3.严格模式下不允许使用with语句,否则将视为语法错误。
4.with关键字的弊端
- 性能问题
使用with关键字后,js引擎不能对这段代码进行优化,,还有就是js压缩工具不能对这段代码进行压缩,这也是影响的一个因素 - 语义不明,难以调试
具体可以参考http://luopq.com/2016/02/14/js-with-keyword
5.对with语句来说,会将指定的对象添加到作用域中。
如:
function bulidUrl(){
var qs = "?debug=true";
with(location){//with语句接收的是location对象,因此with语句的变量对象中就包含了location对象的所有属性和方法,然后这个变量对象被添加到作用域的前端。
var url = href + qs;
}
return url;
//当执行流进入buildUrl函数时,它的执行环境中的活动对象就包括arguments对象,with语句中的location对象,qs,url,所以在with语句中定义的url变量可以在with语句外被访问。
}
我的理解:如果你想引用某个指定对象的方法和属性,可以用with语句。这样,这个指定对象就被添加到作用域链的前端。在with语句块中定义的url变量,可以在buildUrl函数作用域中被访问,with语句块只是一个特例(它也有变量对象,即location,当在内部引用href的时候,是因为可以在当前执行环境的变量对象中找到)
注意
IE8及其之前版本的try-catch语句块中,在catch块外面也可以访问到错误对象,因为在catch语句中捕获的错误对象会被添加到执行环境的变量对象,而不是catch语句的变量对象中。IE9修复了这个问题。