引用错误和全局对象

ReferenceError and the global object

本文关键字:对象 全局 错误 引用      更新时间:2023-09-26

在浏览器中的JavaScript中,window是全局对象,这意味着全局范围内定义的每个变量都是window的子对象。那么为什么我会得到这个结果:

console.log(window.foo); // No error, logs "undefined".
console.log(foo);        // Uncaught ReferenceError: foo is not defined.

小提琴

这两行应该是相同的,不是吗?

因为有了window.foo,您正在显式查找window对象的foo属性,而后一个选项并非如此。在后一个选项中,如果未定义foo,则作为开发人员,您应该能够知道它未定义并获得明确的错误警告,而不是解释器将其设置为自行undefined(如第一种情况),这将导致意外结果。

引用错误:

表示引用不存在的变量时的错误。 尝试取消引用尚未声明的变量时,将引发引用错误。

有关详细信息,请查看本文:

  • 理解JavaScript的"未定义"

引用上面的文章:

如果引用的基值未定义,则认为其不可解析。因此,如果点之前的值未定义,则属性引用是不可解析的。下面的示例将抛出 ReferenceError,但不会,因为 TypeError 首先到达那里。这是因为属性的基值受 CheckObjectCoercible(ECMA 5 9.10 到 11.2.1)的约束,该强制要求在尝试将未定义类型转换为对象时引发 TypeError。

例子:

var foo;
foo.bar; //TypeError (base value, foo, is undefined)
bar.baz; //ReferenceError (bar is unersolvable)
undefined.foo; //TypeError (base value is undefined)

根据定义,既不是属性也不是变量的引用是不可解析的,并且会抛出 ReferenceError,因此:

foo; //ReferenceError

在第一个示例 (window.foo) 中,您正在访问 window 对象的属性。JavaScript 返回"undefined",用于当您尝试访问对象的不存在的属性时。它就是这样设计的。

在第二个示例中,您直接引用变量,由于它不存在,因此会引发错误。

这就是JavaScript的设计和工作方式。

在 JavaScript 中,你可以像这样动态分配对象字段,因此window.foo全局上下文中定义时几乎(见下面的评论)等同于var foo;,而只是突然调用foo会使浏览器恐慌,导致它甚至不知道要查看哪个对象。请注意,如果您这样做:

//when in global context, 'var' sets a property on the window object
var foo;
console.log(foo);
//it will then also log `undefined` instead of throwing the error.
//if you then do:
foo = "abbazabba";
console.log(window.foo);
// it will return "abbazabba"