为什么引用未声明的变量会引发引用异常,而引用未声明的属性却不会呢? [英] Why does referencing undeclared variables throw a reference exception but referencing undeclared properties doesn't?
问题描述
Mozilla说变量是全局对象的属性.如果对象具有未定义的属性,则尝试访问它不会创建引用异常-它只是返回未定义该属性.
Mozilla says that variables are properties of the global object. If an object has a property that isn't defined, then trying to access it does not create a reference exception - it simply returns that the property is not defined.
如果存在这样的全局对象-那么为什么访问不存在的属性(即变量)会导致引用错误?这两种情况之间到底有什么区别?
If there is such a global object - then why does accessing its properties (ie: variables) that do not exist create reference errors? What is precisely the difference between these two scenarios?
示例:
console.log(x) //x is not declared -> reference error
var x = new Object();
console.log(x.property); //console.log: undefined
推荐答案
tl; dr:访问变量的方式会带来所有不同,而不是变化的方式存储.
tl;dr: The way the variable is accessed makes all the difference, not how it is stored.
首先了解一些背景:
基本上有两种方式存储"变量.
There are basically two ways how variables are "stored".
在
In a declarative environment, variables are stored in an internal data structure that is not accessible from user code.
在 object 环境中,变量存储为用户代码可访问对象的属性.全局环境恰好是一个对象环境(比它复杂一些,但让它保持简单).因此,全局变量是全局对象的属性.
In an object environment, variables are stored as properties of a user code accessible object. The global environment happens to be an object environment (it's a bit more complicated than that but lets keep it simple). Therefore global variables are properties of the global object.
那么为什么访问不存在的全局变量会引发错误?因为与变量的存储方式 无关,所以仅访问.
So why does accessing a non-existing global variable throw an error? Because it is not relevant how the variables are stored, only how the are accessed.
foo
和 window.foo
是访问全局变量的两种不同方式.
foo
and window.foo
are simply two different ways of accessing a global variable.
用于评估变量( foo
)的语言规则明确指出,如果变量不存在,则抛出引用错误(同样,无论如何存储).*
The language rules for evaluating a variable (foo
) explicitly say that if the variable doesn't exist, throw a reference error (again, no matter how it is stored).*
用于评估属性访问权限的语言规则(<> window.foo )表示,如果该属性不存在,则应返回 undefined
.
The language rules for evaluating property access (window.foo
) say that if the property doesn't exist, undefined
should be returned.
如果您考虑一下,从一致性的角度来看,这更有意义.无论变量是存储在声明性环境还是对象环境中,访问 foo
都应具有相同的结果.
And if you think about, this makes much more sense from a consistency perspective. Accessing foo
should have the same result, no matter whether the variable is stored in a declarative environment or an object environment.
*:更精确地说:这是 GetValue
函数,该函数将引发错误.解析变量时,几乎在任何地方都会调用 GetValue
(例外情况是 typeof
和分组运算符(...)
).
*: To be more precise: It's the GetValue
function that causes the error to be thrown. GetValue
is called almost everywhere when resolving a variable (exceptions are typeof
and the grouping operator (...)
).
这篇关于为什么引用未声明的变量会引发引用异常,而引用未声明的属性却不会呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!