今天再次阅读“JavaScript高级程序设计时”,才明白什么叫延长作用域,故分享给大家看看
大家应该先明白,跟函数相关的几个概念
执行环境(变量对象可谓是它的衍生物)、作用域、作用域链;
执行环境:是每个函数执行的上下文;可以理解是当前执行函数外层作用域(这其中肯定类似为DOM中文档结构 其中 document(根节点)也就相当于最外层的环境变量)。
作用域:函数当前执行环境。
作用域链:执行环境产生的变量对象构成。 作用域链是保证函数在执行时能够正确访问需要变量和函数;
在JavaScript中,既然只有函数作用和全局作用域,也就是说作用域链最外层就是全局作用域
看看下面一个实例:
var i=0;
function scope(){
console.log(i);
}
上面函数中,在函数中是没有存在i 但是当执行scope时,输出结果为: 0 ;为什么尼?这就是函数作用域链的作用。
延长作用域一: try catch
那我们来看看下面的实例:
(function(window){
try{
throw Error("出错误了");
}catch(e){
alert(e); //alert("Error: 出错误了")
}
console.log(e); //undefind
})(window);
按照前面跟函数相关的几个知识点,我们知道作用域链最里层总是当前函数的执行环境中,那上面代码应该在作用域链中是找不到才对;但是我们看看吧
结果出乎意料: alert("Error: 出错误了") undefind
根据前后结果推断,在执行catch语句块时,JavaScript自动把其执行环境添加作用域链中,但是该语句块执行完后又自动把该执行环境(变量对象)移除
alert(e) == alert("Error:出现错误");
console.log(e) == undefined;
注意: IE8以及更低版本中,把catch中的捕获对象添加到了函数作用域对象中,在IE9后修复这个问题
在IE8中测试结果为:
alert(e) => alert("Error: 出错误了");
console.log(e) => object Error: 出错误了{description: "出错误了",message: "出错误了",name: "Error"}
延长作用域二: with
function scope(){
console.log(location.href
); }
function scope(){ with(location){ console.log(href); } }
上面两种方式是等价的:提前是非严格模式下, 因为严格模式下不支持 with这种方式。在with中,会把当前的对象 location加入 with语句块的变量对象中,并加入作用域链中。当函数执行完后并移除当前with执行对象,也就是说在with外是不能访问的,那我们看看下面实例
function scope(){
with(location){
console.log(href); // http://.......
}
console.log(href); //undefinde
}