在书Secrets of the JavaScript Ninja中,p。 43 - 46,它有一些代码:
function assert(flag, msg) {
if (!flag) {
console.log("Assertion failed for: " + msg);
}
}
function outer() {
var a = 1;
function inner() { }
assert(typeof b === "number", "b is in scope");
var b = 1;
}
outer();
结论是,由于断言失败,“b尚未在范围内,直到声明为止”。但我认为不是这样,因为首先,b
已经具有本地范围,但只是它还不是“数字”。 b
实际上已经是本地范围b
,并且会影响任何全局范围b
。
例如:
var b = 123;
function foo() {
b = 456;
var b = 789;
}
foo();
console.log(b); // prints out 123
因为它打印出123
,所以我们可以看到,当执行第b = 456;
行时,b
已经是本地范围b
。 (即使在作业之前它尚未初始化)。
此外,我们可以打印出来而不是分配给b
:
var b = 123;
function foo() {
console.log(b); // prints out undefined
var b = 789;
}
foo();
console.log(b); // prints out 123
再次,我们可以看到第一次打印输出不是123
,而是undefined
,这意味着b
是本地范围b
,因此{ {1}}实际上已经在本书的范例内了。
以上描述和概念是否正确?
答案 0 :(得分:5)
确实,这本书的结论是错误的。函数内的var b
任何地方意味着b
在函数内部任何位置存在。这就是“吊装”的意思。所有var
和function
声明都会被提升到顶部,无论它们在作用域中出现在何处。尚未分配值。
答案 1 :(得分:2)
关于代码:
assert(typeof b === "number", "b is in scope");
var b = 1;
声明:
“b尚未在范围内,直到声明为”
错了。 b
是'范围'(因为它已声明,它是在执行任何代码之前创建的)但尚未分配值,因此typeof b
返回undefined
并且测试失败。< / p>
以上描述和概念是否正确?
是的,或多或少。一个更简单的证据是:
function foo() {
alert(b);
var b = 5;
}
function bar() {
alert(x);
x = 5;
}
foo() // 'undefined' since b is "in scope" but hasn't been assigned a value yet
bar() // throws an error since x isn't "in scope" until the following line.