2

在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

再一次,我们可以看到第一个打印输出 is not 123but is undefined,这意味着 theb是一个本地范围b,因此,b在本书的示例中,真的已经在范围内。

上述描述和概念是否正确?

4

2 回答 2

5

的确,这本书的结论是错误的。var b 函数内部的任何地方意味着b存在于函数内部的任何地方。这就是“吊装”的意思。所有varfunction声明都被提升到顶部,无论它们出现在范围内的什么位置。该还没有被分配。

于 2013-02-21T08:11:50.100 回答
2

关于代码:

assert(typeof b === "number", "b is in scope");
var b = 1;

该声明:

“b 尚未在范围内,直到它被声明”

是错的。b是“在范围内”(因为它是声明的,它是在执行任何代码之前创建的)但还没有被赋值,所以typeof b返回undefined并且测试失败。

上述描述和概念是否正确?

是的,或多或少。一个更简单的证明是:

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.
于 2013-02-21T08:39:03.757 回答