构造函数总是一个函数对象吗?

时间:2012-05-01 05:15:50

标签: javascript

我正在阅读2011年6月5.1版的最新ECMA-262参考资料。

8.6.2表9中我们关于[[Construct]]内部属性:

  

创建一个对象。通过new运算符调用。该   SpecOp的参数是传递给的参数   新运营商。实现此内部方法的对象   被称为构造函数。

标准并没有说构造函数必须是Function对象。那么我们可以有一个不是函数对象的构造函数对象吗?

Link to the standard as requested

3 个答案:

答案 0 :(得分:4)

答案非常简单。 ES5 § 4.3.4说:

Constructor  Function object that creates and initialises objects.

所以你有它,根据定义,只有一个Function可以是一个构造函数。但是,可能存在主机对象,其行为类似于构造函数,这些构造函数不具有本机Function对象的任何其他属性(例如,在IE中以ActiveX实现的原始XMLHttpRequest对象)。

答案 1 :(得分:3)

虽然定义了术语“构造函数”(作为@RobG pointed out),但没有任何东西可以阻止非“构造函数”对象使用[[Construct]]方法。

这有点令人困惑。这意味着您可以在非new的对象上使用Function运算符(因此不是4.3.4的“构造函数” ),但确实提供了[[Construct]]方法。

请注意,没有一个标准对象符合条件,但host objects可能确实如此。像Java这样的浏览器插件可能会暴露出一些像这样的对象:

new java.lang.String(); // it works, so java.lang.String has a [[Construct]] method
java.lang.String instanceof Function // false
Object.prototype.toString.call(java.lang.String).indexOf('Function') // -1

请注意,即使typeof java.lang.String不是函数,"function"也会返回java.lang.String。根据{{​​3}}(它是具有[[Call]]方法的主机对象)

,这是正确的

答案 2 :(得分:0)

要添加到Pumbaa80的answer(这对评论来说太长了)。

13.2.2增加了混淆,根据该问题,当函数的 construct被执行时,必须执行其call操作(但它不会说当执行非函数对象的construct时必须执行的操作。现在,根据9.11,实现call的对象是可调用的功能对象。

同样根据4.2“函数是可调用对象”。但当然这并不意味着每个可调用对象都是一个函数。

因此,如果我有这个权利,非Function对象可以有Construct方法和Call方法。 java.lang.String就是这样一个例子。