35

请帮助我理解为什么以下代码有效:

<script>
    var re = RegExp('\\ba\\b') ;
    alert(re.test('a')) ;
    alert(re.test('ab')) ;
</script>

第一行没有new运算符。

据我所知,JavaScript中的构造函数是一个初始化操作符创建的对象的函数,new它们并不意味着返回任何东西。

4

2 回答 2

43

通常,如果某些东西被记录为构造函数,请new与它一起使用。但是在这种情况下,RegExp对于您将其作为函数调用的情况,它具有定义的“工厂”行为。请参阅 ECMAScript (JavaScript)规范的第 15.10.3 节(链接到即将发布的规范;新规范中的节号相同,您可以从 ECMA主页[右侧]下载;我不想直接链接到 ~4MB PDF 文件):

15.10.3 作为函数调用的 RegExp 构造函数
15.10.3.1 RegExp(pattern, flags)
如果 pattern 是对象 R,其 [[Class]] 属性为“RegExp”且 flags 未定义,则返回 R 不变。否则调用 RegExp 构造函数 (15.10.4.1),将模式和标志参数传递给它,并返回由该构造函数构造的对象。

您实际上可以定义自己的 JavaScript 构造函数以允许省略new关键字(通过检测它们已被作为函数调用,然后转身并正确调用自己),但我不建议这样做,因为它会导致误导性代码。(而且你不能用class语法来做到这一点,你必须使用旧的、更笨重的function语法。)

于 2009-12-18T14:11:22.503 回答
13

+1 TJ克劳德有它。ECMAScript 标准竭尽全力定义内置构造函数在作为普通函数调用时的行为。通常它只是简单地将自己作为构造函数回调,但也有一些更复杂的情况。

javascript [...] 中的构造函数并不意味着返回任何东西

一般来说,构造函数可以忽略this并只返回一个独立的对象:

function Thing() {
    return {'foo': 1};
}

在这种情况下,您同样可以将该函数用作构造函数(使用new)或普通函数。

如果构造函数没有返回任何东西,就像构造函数的通常模式一样,new操作符本身会确保它返回创建的新对象并作为this. 在这种情况下,您必须使用new.

最好不要依赖构造函数作为裸函数工作,内置构造函数的替代行为很少有任何用处,所以通常你应该坚持使用new.

于 2009-12-18T14:21:06.263 回答