简体   繁体   English

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

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

I'm trying to wrap my head around the behavior of reference errors thrown in JavaScript. 我试图围绕JavaScript引发的引用错误的行为。

In the following example, a ReferenceError is thrown at the second line, and execution breaks: 在以下示例中,将在第二行引发ReferenceError ,并执行中断:

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

alert('Completed');

Whereas in this example, the code completes successfully, though obj.func1 remains undefined : 而在此示例中,代码成功完成,但obj.func1仍未undefined

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

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

alert('Completed');

My assumption was that an error would be thrown at the second line just the same, and when that wasn't the case, I'd have expected obj.func1 to properly reference func2 , but I've been double blind-sided. 我的假设是错误会在第二行被抛出同样的情况,而当情况并非如此时,我已经预期obj.func1会正确引用func2 ,但我已经双盲。 So what exactly is going on here? 那到底是怎么回事?

This is due to Javascript variable declaration "hoisting". 这是由于Javascript变量声明“提升”。

A variable declared with var is visible everywhere in the function, so there's no Reference Error . var声明的变量在函数中到处都是可见的,因此没有Reference Error However, it doesn't actually receive its value until you execute the statement that initializes it. 但是,在执行初始化它的语句之前,它实际上不会收到它的值。 So your second example is equivalent to: 所以你的第二个例子相当于:

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

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

alert('Completed');

In this rewrite, you can see that the variable exists when you perform the assignment to obj.func1 . 在此重写中,您可以在执行对obj.func1的赋值时看到该变量存在。 But since it doesn't yet have a value, you assign undefined to obj.func1 . 但由于它还没有值,因此将undefined分配给obj.func1 Assigning to func2 later doesn't change that. 稍后分配给func2不会改变它。

var is hoisted; var被悬挂; the variable exists throughout the current scope. 变量存在于整个当前范围内。 Thus, the second example is equivalent to: 因此,第二个例子相当于:

var obj;
var func2;

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

alert('Completed');

Thus, when you do the assignment, The name func2 is known, but undefined . 因此,当您执行赋值时,名称func2是已知的,但undefined In the first example, it is unknown, which raises ReferenceError . 在第一个例子中,它是未知的,它引发了ReferenceError

Your func2 variable is not visible. 您的func2变量不可见。 That's why obj.func1 remains undefined. 这就是为什么obj.func1仍未定义的原因。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM