为什么有些构造函数可以不使用`new`操作符来调用?

问题描述 投票:0回答:2

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

var re = RegExp('\\ba\\b') ;
console.log(re.test('a')) ;
console.log(re.test('ab')) ;

第一行没有

new
运算符。

据我所知,JavaScript中的构造函数是一个初始化由运算符

new
创建的对象的函数,它们并不意味着返回任何内容。

javascript constructor new-operator object-construction
2个回答
43
投票

一般来说,如果某个东西被记录为构造函数,请使用

new
。但在这种情况下,
RegExp
对于您将其作为函数调用的情况具有定义的“工厂”行为。请参阅 ECMAScript (JavaScript) 规范第 15.10.3 节(链接到即将发布的规范;新规范中的章节编号相同,您可以从 ECMA 首页 [右侧side]; 我不想直接链接到 ~4MB PDF 文件):

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

您实际上可以定义自己的 JavaScript 构造函数以允许省略

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


13
投票

+1 TJ Crowder 拥有它。 ECMAScript 标准不遗余力地定义内置构造函数作为普通函数调用时的行为。通常它只是将自身作为构造函数回调,但也有一些更复杂的情况。

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

一般来说,构造函数可以忽略

this
并只返回一个独立的对象:

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

在这种情况下,您同样可以将该函数用作构造函数(使用

new
)或普通函数。

如果构造函数不返回任何内容(这是构造函数的通常模式),则

new
运算符本身确保它返回创建并作为
this
传递的新对象。在这种情况下,您必须使用
new

最好不要依赖作为裸函数工作的构造函数,并且内置构造函数的替代行为很少有任何用处,因此通常您应该坚持使用

new

© www.soinside.com 2019 - 2024. All rights reserved.