({
x: 10,
foo: function () {
function bar() {
console.log(x);
console.log(y);
console.log(this.x);
}
with (this) {
var x = 20;
var y = 30;
bar.call(this);
}
}
}).foo();
({
x: 10,
foo: function () {
function bar() {
console.log(x);
console.log(y);
console.log(this.x);
}
with (this) {
var x = 20;
var y = 30;
bar.call(this);
}
}
}).foo();
等价转换为==>
var obj={
x: 10,
foo: function () {
var x,y;
function bar() {
console.log(x);//1
console.log(y);//2
console.log(this.x);//3
}
with (this) {//4
x = 20;//5
y = 30;//6
bar.call(this);//7
}
console.log(x);//8
x=999;
console.log(x);//9
}
};
obj.foo();//10
with语句中的变量x,y声明提前到函数顶部;
with关键字会将with对应的对象添加到当前其所在函数作用域链的头部位置,也就是with语句块中的属性首先从头部位置的对象开始找,找不到再往上...等with语句执行完后,会恢复原来你的函数作用域链。
对于以上的问题:obj.foo();
执行,[4]处的this为obj对象,[5]x=20;
obj有x属性,故obj.x属性值被更新为20,foo
函数体的x变量值没有被赋值;[6]y=30;
obj没有y属性,故foo
函数体中的变量赋值为30;bar.call(this);
执行时,obj的属性x值为20,
[1]输出为undefined
[2]输出为30
[3]输出为20
[8]输出为undefined
[9]输出为999
({
x: 10,
foo: function () {
var x, y
function bar() {
console.log(x);
console.log(y);
console.log(this.x);
}
this.x = 20;
y = 30;
bar.call(this);
}
}
}).foo();
不要用with,也不用去学 何乐而不为
首先
var obj = {x:10,foo:function(){}};
然后执行foo
obj.foo();
foo中做了两件事?
声明了一个bar函数and延长obj的作用域
with干了些什么?
说明:在声明x,y时with先要确定this中有没有这两个属性,有的话就直接改变,没有的话就声明一个新的
所以:这里this的x被改变了,而y被声明
接下来执行`bar.call(this)`
其实就是在obj下执行bar
第一行输出console.log(x),x没有声明x所以为undefined(那个x是this的x)
第二行输出console.log(y),y声明了的所以可以取到值30
第三行输出console.log(this.x),毫无疑问是改变后的x值咯20