如果在声明变量之前使用变量,为什么不会抛出 ReferenceError?

Why is no ReferenceError being thrown if a variable is used before it’s declared?

我正在努力解决 JavaScript 中引发的引用错误的行为。

在下面的示例中,在第二行抛出一个 ReferenceError,并且执行中断:

var obj = {};
obj.func1 = func2;

alert('Completed');

而在此示例中,代码成功完成,尽管 obj.func1 仍然 undefined:

var obj = {};
obj.func1 = func2;

var func2 = function() {
    alert('func2');
};

alert('Completed');

我的假设是第二行同样会抛出一个错误,如果不是这样,我会期望 obj.func1 正确引用 func2,但我一直双盲。那么这里到底发生了什么?

var吊装;该变量存在于整个当前范围内。因此,第二个例子等同于:

var obj;
var func2;

obj = {};
obj.func1 = func2;
func2 = function() {
    alert('func2');
}

alert('Completed');

因此,当您进行赋值时,名称 func2 是已知的,但 undefined 是已知的。在第一个示例中,它是未知的,这引发了 ReferenceError.

这是由于 Javascript 变量声明 "hoisting"。

var声明的变量在函数中随处可见,所以没有Reference Error。但是,在您执行初始化它的语句之前,它实际上并没有收到它的值。所以你的第二个例子相当于:

var func2;
var obj = {};
obj.func1 = func2;

func2 = function() {
    alert('func2');
};

alert('Completed');

在这个rewrite中,你可以看到当你对obj.func1进行赋值时,这个变量是存在的。但由于它还没有值,您将 undefined 分配给 obj.func1。稍后分配给 func2 不会改变这一点。

您的 func2 变量不可见。这就是 obj.func1 保持未定义的原因。

var obj = {};
var func2 = function() {
    alert('func2');
    return "Test";
};
    
obj.func1 = func2;
   
alert('Completed');