今天再看一段代码,感觉自已对with的理解很不到位啊,由于with语句在开发中基本不会使用,而且很多书上也不建议使用with来改变函数的作用域,并且在严格模式下with语句是禁用的。
var obj = {
x: 10,
foo: function () {
with(this) {
var x = 20;
}
}
}
console.log(obj.x); // 10
obj.foo();
console.log(obj.x); // 20
我们可以发现,由于是在with语句绑定到obj作用域下定义的x,所以这个x不是任何的变量,这个x就是改变了obj.x的值。with语句会在作用域链前端添加一个变量对象,这个变量对象会将obj的属性和方法作为参数传入这个with的作用域中,然后就像执行上下文那样了,并且with这个作用域内声明的变量,只在这个作用域内有效。
var obj = {
x: 10,
foo: function () {
with(this) {
var x = 20; // with也可以理解为一个函数,
// 其实var x;这就话是没有用的(执行上下文),因为这个作用域下面有x,注意this这里参数,这个是按共享传递,
var y = 30;
}
}
}
obj.foo();
console.log(obj.x); // 20
console.log(obj.y); // undefined
在with中闭包也就有效的,this指向的是全局
那下面来看一个比较综合的例子:
var o={
x: 10,
foo: function () {
with (this) {
function bar() {
console.log(x);
console.log(this.x);
}
var x = 20;
(function() {
bar();
// undefined
// undefined
// 闭包,this指向的是全局,x在全局未定义所以undefined
})();
bar.call(this);
// undefined
// 20
}
}
}
o.foo();
this保存的是obj的引用,
第一个输出:
(1)bar()是闭包,闭包拥有全局作用域,可以访问到with作用域内定义的变量,但是当前with作用域内定义的变量并没有x,这个x并不是局部变量,这个是参数,执行上下文var x;被提前但是被忽略
(2)由于是闭包,所以this.x指向的是全局
第二个输出:
(1)在with的作用域内,并且绑定到了this下,但是在with作用域内并不存在定义的x变量,所以是undefined
(2)this就是obj,相当于访问obj.x