为什么引用未声明的变量会引发引用异常,而引用未声明的属性却不会?
Why does referencing undeclared variables throw a reference exception but referencing undeclared properties doesn't?
Mozilla says that variables are properties of the global object。如果对象具有未定义的 属性,则尝试访问它不会创建引用异常 - 它只是 returns 未定义 属性。
如果存在这样的全局对象 - 那么为什么访问其不存在的属性(即:变量)会产生引用错误?这两种情况到底有什么区别?
示例:
console.log(x) //x is not declared -> reference error
var x = new Object();
console.log(x.property); //console.log: undefined
tl;dr: 访问变量的 方式 造成了所有差异,而不是它的存储方式。
首先是一些背景:
基本上变量有两种方式"stored"。
在 declarative environment 中,变量存储在用户代码无法访问的内部数据结构中。
在 object environment 中,变量存储为用户代码可访问对象的属性。全局环境恰好是一个对象环境(它比这复杂一点,但让我们保持简单)。因此全局变量是全局对象的属性。
那么为什么访问一个不存在的全局变量会抛出错误呢?因为变量如何存储不相关,只有变量如何访问.
foo
和 window.foo
只是访问全局变量的两种不同方式。
评估变量的语言规则 (foo
) 明确指出,如果变量不存在,则抛出引用错误(同样,无论它如何存储)。*
The language rules 用于评估 属性 访问权限 (window.foo
) 表示如果 属性 不存在,则应返回 undefined
。
如果您考虑一下,从一致性的角度来看,这更有意义。访问 foo
应该有相同的结果,无论变量是存储在声明环境还是对象环境。
*:更准确地说:是 GetValue
函数导致抛出错误。 GetValue
在解析变量时几乎无处不在(例外是 typeof
和分组运算符 (...)
)。
Mozilla says that variables are properties of the global object。如果对象具有未定义的 属性,则尝试访问它不会创建引用异常 - 它只是 returns 未定义 属性。
如果存在这样的全局对象 - 那么为什么访问其不存在的属性(即:变量)会产生引用错误?这两种情况到底有什么区别?
示例:
console.log(x) //x is not declared -> reference error
var x = new Object();
console.log(x.property); //console.log: undefined
tl;dr: 访问变量的 方式 造成了所有差异,而不是它的存储方式。
首先是一些背景:
基本上变量有两种方式"stored"。
在 declarative environment 中,变量存储在用户代码无法访问的内部数据结构中。
在 object environment 中,变量存储为用户代码可访问对象的属性。全局环境恰好是一个对象环境(它比这复杂一点,但让我们保持简单)。因此全局变量是全局对象的属性。
那么为什么访问一个不存在的全局变量会抛出错误呢?因为变量如何存储不相关,只有变量如何访问.
foo
和 window.foo
只是访问全局变量的两种不同方式。
评估变量的语言规则 (foo
) 明确指出,如果变量不存在,则抛出引用错误(同样,无论它如何存储)。*
The language rules 用于评估 属性 访问权限 (window.foo
) 表示如果 属性 不存在,则应返回 undefined
。
如果您考虑一下,从一致性的角度来看,这更有意义。访问 foo
应该有相同的结果,无论变量是存储在声明环境还是对象环境。
*:更准确地说:是 GetValue
函数导致抛出错误。 GetValue
在解析变量时几乎无处不在(例外是 typeof
和分组运算符 (...)
)。