Javascript:z = z || []不使用VAR时会抛出错误 - 为什么?

时间:2012-01-30 16:00:57

标签: javascript var scoping operator-precedence hoisting

出于好奇心,为什么javascript接受

var z = z || [];

初始化z(z可能最初定义)

但没有var,它会抛出错误(在全局空间中)

z = z || [];

(如果z先前未定义)

在全球空间中,您不需要使用VAR,但我得到它可能是不好的做法。

在你说这是像

这样的问题的重复之前

What is the purpose of the var keyword and when to use it (or omit it)?

请注意 的声明“如果您在全球范围内,那么没有区别。”

显然,根据我的工作实例,这并非100%正确。

这是一个怪癖还是有合法的逻辑?


在我学会的时候添加答案摘要:

感谢Tim(见下文),我误解的关键是没有意识到这一点(javascript的基础)

  

var z;如果z已经存在,则绝对没有任何作用

这就是这个表达式似乎有两种方式,如果你不正确,假设“var z”总是初始化。

从左侧开始,“var z”只是确保定义了z,但如果已经存在,则实际上不会影响任何现有值。然后在右边,如果z已经存在,则使用它,否则,变量刚刚被声明(但是为空),因此它不会被使用但不会引发错误。

这是关于Javascript中这种范围和提升问题的优秀文章: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

非常感谢minitech和其他所有贡献者!

3 个答案:

答案 0 :(得分:10)

效果是正确的。 var将始终立即声明其“操作数”,而当您不声明它时,您的脚本会尝试使用未定义的变量并引发错误。

如果你处于全局范围,你可以分配一个不存在的变量,它将具有与声明它相同的效果,这可能是不好的做法。当然,在你的情况下,它是未定义的。话虽这么说,虽然它可能是出于好奇心,但你从不

var z = z || [];

因为这样做没有任何意义。相反,你可以这样做:

if(!window.z) {
    window.z = [];
}

。事实上,当我在全局范围内声明事物(从不;))时,我使用window.something代替,因为它使我的意图更加明确。

答案 1 :(得分:6)

z = z || []将抛出范围链中没有z的任何范围(全局或非全局)。原因是表达式首先尝试在右侧检索名为z的现有变量的值,如果不存在则会出错。

var z = z || []不抛出错误的原因是在执行表达式之前创建了变量z(如果它尚不存在),这种效应通常称为提升

另一方面,为未解析的标识符(例如z = 2)分配值将在任何范围内无错误地工作(ECMAScript 5严格模式除外,它禁止它并抛出)。如果无法解析标识符,它将作为最终对象的属性添加到作用域链中,这是全局对象,因此给出了创建全局变量的外观。

答案 2 :(得分:4)

您可以指定一个未声明的变量z = 123;但是你可能不会尝试阅读z = z || []所做的那个。