我只是在github上学习You-don't-know-js书,目前是范围闭合,第2章:https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch2.md
我遇到了一个我不清楚的问题:在 with{ } 语句中使用"var"声明一个变量。 以下是对此的解释:
注意:即使 with 块将对象视为词法范围, 带有块的普通var 声明将不被作用域 到块,而是包含函数范围。
根据这个解释,我对本章提供的代码进行了一些更改:
function foo(obj) {
with (obj) {
var a = 2; //Here I added "var" declaration
}
console.log('foo, '+ a) //Here I added console function to see if a is in foo scope
}
var o1 = {
a: 3
};
var o2 = {
b: 3
};
foo( o1 ); // foo, undefined
console.log( o1.a ); //2
foo( o2 ); // foo, 2
console.log( o2.a ); //undefined
对于 Foo(O2(,我的理解是,因为 O2 没有名为"a"的属性,所以 with 块中的 var 声明只是在 foo 函数范围内创建了一个变量 a,结果是有意义的。 但是对于 foo(o1(,var 声明只是将 o1.a 更改为值 2,但为什么 console.log('foo, '+a(显示 'foo, undefined'?据我了解,结果应该是"foo, 2"或引用错误:未定义 a。
谁能解释这个问题?谢谢。
编译器的作用:
function foo(obj) {
var a; // hoisted
with (obj) {
a = 2; // take a from object if exists, otherwise take variable
}
console.log('foo, '+ a);
}
第一种情况在函数的作用域中创建一个a
变量,然后删除/提升var
语句,只保留赋值部分。
虽然obj
包含一个属性a
,但该值与with
语句一起分配给对象的属性。
本地a
没有收到任何价值。
在第二次调用中,没有a
的属性,因此变量a
获取一个值。