JavaScript中函数返回数组时使用`new`关键字的含义

6
我是一个有用的助手,可以为您翻译文本。
我在尝试使用new关键字时遇到了问题,并且找不到对此行为的解释。假设我们有一个返回整数的函数:
(在firebug中)
>>> function x() { return 2; }
>>> x()
2
>>> new x()
x { }

但如果函数返回一个数组:

>>> function y() { return [2]; }
>>> y()
[2]
>>> new y()
[2]

为什么会这样呢?


2
离题:我知道你只是在尝试,但早期养成习惯很值得,如果你正在尝试,你可能还不知道这一点:JavaScript代码中压倒性的约定是构造函数的名称(使用new而不仅仅是直接调用的函数)以大写字母开头,所有其他函数的名称以小写字母开头。因此,Foo将是一个构造函数,而foo则不是。 - T.J. Crowder
1
@Pete2k:看起来kbok正在JavaScript控制台中玩耍。此外,在JavaScript中分号是可选的,语句也可以通过EOL终止。 - mu is too short
这是因为我正在火狐浏览器的控制台中输入它。 - slaphappy
你正在Firebug中实时输入JavaScript代码,我不知道你可以这样做。那么[2]是返回的内容吗(也就是说它本身不是代码)? - Exitos
@Pete2k:是的。你可以在Firebug、Chrome的开发工具以及大多数其他工具的控制台中完成这个操作。 - T.J. Crowder
显示剩余2条评论
2个回答

16
new 运算符有一个有趣的行为:它返回由运算符创建的对象,除非构造函数返回另一个对象。构造函数的任何非对象返回值都将被忽略,这就是为什么当您返回 2 时看不到结果的原因。
执行 new x() 时会发生以下情况:
  1. 解释器创建一个新的空白对象。
  2. 它将对象的基础原型设置为 x.prototype
  3. 它使用新对象作为 this 调用 x
  4. 在正常情况下,x 不返回任何内容,new 表达式的结果是第 1 步创建的新对象。但是,如果 x 返回一个非 null 的对象引用,则该对象引用是 new 表达式的结果,而不是第 1 步创建的对象。任何其他类型的返回值(例如 null、原始数值、原始字符串、undefined 等)都将被忽略;它必须是一个非 null 的对象引用,才能优先于 new 创建的对象。
new 运算符对对象引用的这种特殊处理允许您替换 new 创建的对象。这在一些有限的情况下可能很方便,但是绝大部分时间,用于 new 的函数(称为构造函数)都不应该返回任何东西。

如果你想轻松阅读一些内容(哈哈),可以参考规范的第13.2.2节"[[Construct]]"),该规范详细说明了这个概念。你也可以查看相关的HTMLPDF文件。该规范被第11.2.2节"new运算符")所引用。


链接:http://ecma262-5.com/ELS5_HTML.htm#Section_13.2.2 :) 我们总是这样做吗?我提供简短的摘要,您详细介绍一下吗? ;) - Felix Kling
@Felix:是的,我还在考虑那个网站,因此链接到 ECMA 的规范。不过做得很漂亮。 - T.J. Crowder

5

因为数组是一个对象,但数字2不是。

如果你使用new关键字调用函数,则必须返回一个对象。如果没有明确指定,它会自动返回this(这是一个继承自funcName.prototype的空对象)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接