您的位置:首页 > Web前端 > JavaScript

关于js with语句的一些理解

2015-07-08 08:24 513 查看
今天看到js的with语句部分,书中写到,with语句接收的对象会添加到作用域链的前端并在代码执行完之后移除。看到这里,我有两点疑问,添加到作用域链前端是不是指对象会被放置到作用域链的最底部,然后查找变量时最先查找这个对象(按照我的理解,js的作用域链查找变量的过程是一个冒泡的过程,底部开始往上走,找到了就停止冒泡),第二点就是,执行之后移除是不是指with语句之后就移除那个对象。于是写了一个简单的例子来验证一下。

var b = {a:2};

function sayA(){
var a = 1;
with(b){alert(a);}
alert(a);
}

sayA();


代码运行结果是2和1。这证实了我之前的猜想,因为正常情况,位于作用域链底部的应该是函数的局部变量a,然而with语句中的a却是对象b的字段a,这证明对象b占据了作用域链中最底部的位置。而with语句之后的a的值又变成了1,说明对象b已从作用域链最底部移除。我自己认为在with语句中,这时的执行环境就是对象b,而不是函数,所以首先访问b中的a值。

我尝试在函数外直接访问a,结果当然是undefined,因为这时的执行环境应该是全局环境,而全局环境并没有这个a值,只有通过b.a才可以访问b中的a,所以可以这样说with语句其实还提供了简写访问对象字段的途径。假设b中有50个字段,你要全部访问,正常情况你要写50个b.xxx,而使用with语句只要直接写字段名就行了。

然而,我又有了一个疑问,我在with语句中创建一个变量,这个变量究竟属于谁。如果按照我的理解,这个变量应该属于对象b。

var b = {a:2};

function sayA(obj){
var a = 1;
with(b){a=5;c = 6;}
alert(c);
}

sayA();
alert(b.c);
alert(b.a);


但是, 运行结果是6、undefined和5。这说明with语句中的对象并不是作为执行环境添加到作用域链中的,仅仅是作为一个变量添加到with语句所在的执行环境之中,with语句中的变量还是属于with语句所在的执行环境(这里是函数sayA),而对b的字段的改变也会真正影响到b。

总结

在with语句块中,只是改变了对变量的遍历顺序,由原本的从执行环境开始变为从with语句的对象开始。当尝试在with语句块中修改变量时,会搜索with语句的对象是否有该变量,有就改变对象的值,没有就创建,但是创建的变量依然属于with语句块所在的执行环境,并不属于with对象。

离开with语句块后,遍历顺序就会再次变成从执行环境开始。

其实概括来说,和书本所总结的是一致的,with语句接收的对象会添加到作用域链的前端并在代码执行完之后移除。

本人见解,如有错误,欢迎指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: