【问题标题】:ReferenceError and the global objectReferenceError 和全局对象
【发布时间】:2012-04-23 13:50:04
【问题描述】:

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

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

Fiddle

这两行应该是一样的吧?

【问题讨论】:

    标签: javascript window referenceerror global-object


    【解决方案1】:

    在您的第一个示例 (window.foo) 中,您正在访问窗口对象的属性。当您尝试访问对象的不存在属性时,JavaScript 返回“未定义”。就是这样设计的。

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

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

    【讨论】:

      【解决方案2】:

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

      Reference Error:

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

      查看这篇文章了解更多信息:

      引用以上文章:

      一个引用被认为是不可解析的如果它的基值是未定义的。因此,如果点之前的值未定义,则属性引用是无法解析的。下面的例子会抛出一个 ReferenceError 但它不会因为 TypeError 首先到达那里。这是因为属性的基值受 CheckObjectCoercible(ECMA 5 9.10 通过 11.2.1)的约束,当尝试将 Undefined 类型转换为 Object 时会引发 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
      

      【讨论】:

        【解决方案3】:

        在 JavaScript 中,您可以像这样动态分配对象字段,所以window.foo几乎(参见下面的 cmets) 等效于 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" 
        

        【讨论】:

        • window.foo 不等于 var foo
        • @TimDown。你能详细说明一下吗?也许在答案中?
        • @TimDown & @gdoron 好吧,这有点不真实——我的意思是 window.foo 在全局上下文中声明时等同于 var foo
        • 它仍然不完全等价。例如,可以删除已显式设置的全局对象的属性(window.foo = "bar"; 之后,delete window.foo; 删除foo 属性并返回true)而不能删除变量(@ 之后987654332@, delete window.foo; 什么都不做,返回false)。
        • 我猜你正在控制台中尝试它,这会改变一些事情,因为控制台使用eval() 并且使用eval() 执行的代码与正常执行的代码的行为略有不同。请改为在测试页面中尝试。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        • 2019-08-26
        • 2014-08-22
        • 2011-12-31
        • 2016-05-09
        相关资源
        最近更新 更多