'悬挂'JavaScript变量

Gra*_*ful 31 javascript hoisting

我不完全理解为什么以下显示"悬挂"到最后.

var x = 'set';
var y = function () 
{
    // WHAT YOU DON'T SEE -> var x; 
    // is effectively "hoisted" to this line!

    if (!x) 
    { 
        // You might expect the variable to be populated at this point...it is not
        // though, so this block executes
        var x = 'hoisted'; 
    }

    alert(x); 
}

//... and this call causes an alert to display "hoisted"
y();
Run Code Online (Sandbox Code Playgroud)

任何指针将不胜感激.

the*_*eye 34

引用MDN文件var提升,

因为在执行任何代码之前处理变量声明(以及一般的声明),所以在代码中的任何地方声明变量等同于在顶部声明它.这也意味着变量可以在声明之前使用.此行为称为"提升",因为看起来变量声明被移动到函数或全局代码的顶部.

因此,在您的情况下,JavaScript知道在函数的某处定义了一个局部变量(不是在外面声明的那个) x,但是在执行到达赋值的赋值语句之前,它不知道它的实际值x.(声明在编译期间处理,分配在执行时间内完成)直到分配完成,undefined将使用默认值.既然undefined是假的,那就是条件

if (!x) {
Run Code Online (Sandbox Code Playgroud)

满意并执行赋值语句.这就是你进入hoisted警报框的原因.


假设你没有x在函数内部声明,

var x;

var y = function () {
    if (!x) {
        x = 'hoisted';
    }
    alert(x);
}

y();
alert(x);
Run Code Online (Sandbox Code Playgroud)

这里,由于x未在函数内的任何位置声明,因此在运行时,JavaScript将x在更高的范围内查找.在这种情况下,它在函数外部找到它.所以,这x将被使用.既然你分配hoistedx,内心alert也会说hoisted和离开功能后,alert(x)也会发出警报hoisted.


dfs*_*fsq 12

变量声明提升到范围的顶部.所以你的代码等同于:

var x = 'set';
var y = function () {
    var x;
    if (!x) {
        x = 'hoisted';
    }
    alert(x);
}

y();
Run Code Online (Sandbox Code Playgroud)

y被执行时,var x阴影范围外x这样的内部的y功能xundefined声明的第一行之后.

  • 如果`x`来自外部作用域,@ mhkyazd根本不在函数的任何地方写`var x`,因此它不会被覆盖. (2认同)