在JavaScript中,当一个局部变量被提升时,它甚至在声明之前就已经在作用域中了吗
In JavaScript, when a local variable is hoisted, is it in scope even before it is declared?
在《JavaScript忍者的秘密》一书中,第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
,因此,b
在本书的例子中确实已经在范围中了。
以上描述和概念正确吗?
var b
任何位置意味着b
存在于函数内的任何位置。这就是"提升"。所有var
和function
声明都被提升到顶部,无论它们在范围中的位置如何。值还没有分配。
关于代码:
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.
相关文章:
- 当指令中已经给定作用域时,如何访问控制器中声明的函数
- try声明变量的作用域
- 将“*”分配给作用域中声明的变量的角度错误
- 节点.js变量声明和作用域
- jQuery 解绑在作用域中声明的事件
- 在另一个作用域中声明变量
- 在JS“if”语句参数中,是否有用于声明本地作用域变量的简明语法
- 阻止作用域声明..TypeScript和Asp.net MVC 5
- AngularJS:块作用域声明(let、const、function、class)在严格模式之外还不支持
- 根据用户输入声明多个作用域
- 为什么条件块中的函数声明在Chrome中提升到函数作用域,而在Firefox中不是?
- 如果在上层作用域中声明变量,则变量在局部作用域中是未定义的,并且在未执行的语句中在局部作用域中声明同名的变量
- Javascript:虽然变量是在全局作用域中声明的,但它在函数内部仍然是未定义的
- 在作用域中声明函数并稍后调用它
- 将作用域变量传递给在该作用域之外声明的闭包
- 声明前作用域中的函数
- 在文档内声明局部变量,或者在不同作用域的函数内声明局部变量
- Javascript作用域:在forEach循环内部声明的变量,而不是在forEach循环外部
- Javascript变量作用域——在函数外部声明的变量
- 在nodejs/commonjs模块的根作用域中声明对象——用var还是不用var