Javascript 起重和范围

Javascript 起重和范围,javascript,scope,hoisting,Javascript,Scope,Hoisting,为什么foo函数日志未定义? 第一个文本变量是全局变量,因此foo应该有权访问它 var text = "outside"; function foo() { console.log(text); var text = "inside"; } foo(); 即使var语句在console.log语句之后,声明也会被提升到函数的开头。因此,这声明了一个局部变量,该局部变量将覆盖全局变量。但是初始化直到您真正到达console.log语句之后的语句时才会发生 因此,您的函数等价

为什么foo函数日志未定义? 第一个文本变量是全局变量,因此foo应该有权访问它

var text = "outside";

function foo() {
    console.log(text);
    var text = "inside";
}

foo();
即使var语句在console.log语句之后,声明也会被提升到函数的开头。因此,这声明了一个局部变量,该局部变量将覆盖全局变量。但是初始化直到您真正到达console.log语句之后的语句时才会发生

因此,您的函数等价于:

function foo() {
    var text;
    console.log(text);
    text = 'inside';
}
如果您没有使用var声明,那么您将继续使用全局变量,直到console.log之后才会发生重新分配。

即使var语句在console.log语句之后,声明也会被提升到函数的开头。因此,这声明了一个局部变量,该局部变量将覆盖全局变量。但是初始化直到您真正到达console.log语句之后的语句时才会发生

因此,您的函数等价于:

function foo() {
    var text;
    console.log(text);
    text = 'inside';
}

如果您没有使用var声明,那么您将继续使用全局变量,直到console.log之后才会进行重新分配。

Do return text;和alertfoo@Jonasw不要对调试语句使用警报。请返回文本;和alertfoo@Jonasw不要在调试语句时使用alert。我认为值得一提的是javascript实际上并没有提升。这种行为实际上是第一次编译过程的结果。由此产生的行为与吊装相同,但从技术上讲,实际上没有任何内容被挂起。@Barmar请务必注意,从foo函数中删除var会使foo使用全局文本variable@mhodges这与提升之间的有效区别是什么?我相信真正的提升实际上是在编译器读取之前移动代码中的声明。然而,在Javascript中,编译器需要2次传递。一个用来获取LHS声明,另一个用来进行RHS评估/赋值,提供与提升相同的行为/功能。@mhodges每个人都称之为提升。由于行为无法区分,所以内部机制并不重要。我认为值得一提的是,javascript实际上并没有提升。这种行为实际上是第一次编译过程的结果。由此产生的行为与吊装相同,但从技术上讲,实际上没有任何内容被挂起。@Barmar请务必注意,从foo函数中删除var会使foo使用全局文本variable@mhodges这与提升之间的有效区别是什么?我相信真正的提升实际上是在编译器读取之前移动代码中的声明。然而,在Javascript中,编译器需要2次传递。一个用来获取LHS声明,另一个用来进行RHS评估/赋值,提供与提升相同的行为/功能。@mhodges每个人都称之为提升。由于行为无法区分,因此内部机制并不重要。