【问题标题】:Why is no ReferenceError being thrown if a variable is used before it’s declared?如果在声明变量之前使用了变量,为什么不会抛出 ReferenceError?
【发布时间】:2016-05-30 03:29:07
【问题描述】:

我正在努力思考 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,但我已经加倍了盲目的。那么这里到底发生了什么?

【问题讨论】:

标签: javascript variable-declaration referenceerror hoisting


【解决方案1】:

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

var obj;
var func2;

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

alert('Completed');

因此,当您执行分配时,名称 func2 是已知的,但 undefined。在第一个例子中,它是未知的,它引发了ReferenceError。

【讨论】:

    【解决方案2】:

    这是由于 Javascript 变量声明“提升”。

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

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

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

    【讨论】:

    • obj 的初始化与它的声明有什么关系?我理解,因为无论如何它都会立即发生,没有实际区别,但这是直译吗?
    • 他直到 obj 被初始化后才引用它,因此在声明期间或之后初始化它实际上没有区别。所以我没有费心重写那部分,因为它与问题无关。
    • 我想我只是担心你的例子是否有点模糊了行为,如果这个想法是 declarations 专门被提升。
    • 只有在声明之前尝试使用变量时,声明和初始化之间的区别才有意义。如果所有的用途都在后面,没有区别,所以没有必要显示重写。
    【解决方案3】:

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

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

    【讨论】:

    • 我很清楚在分配 func1 之前定义 func2 会解决错误。这不是一个真正的问题,只是我在修修补补时发现的一些奇怪的东西。
    猜你喜欢
    • 2016-03-17
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2011-07-06
    相关资源
    最近更新 更多