我注意到并非所有 Javascript 函数都是构造函数。
var obj = Function.prototype;
console.log(typeof obj === 'function'); //true
obj(); //OK
new obj(); //TypeError: obj is not a constructor
问题 1:如何检查函数是否为构造函数,以便可以使用 new
关键字调用它?
问题 2:当我创建一个函数时,是否可以让它 不是 构造函数?
原文由 Mingtao Sun 发布,翻译遵循 CC BY-SA 4.0 许可协议
一点背景:
ECMAScript 6+ 区分 _可调用_(可以在没有
new
下调用)和可 _构造的_(可以通过new
调用)函数:class
语法创建的函数 _不可调用_。Function
构造函数)是可调用和可构造的。关于
Function.prototype
Function.prototype
是所谓的 不可构造的 内置函数。从规格:Function.prototype
的值是在运行时初始化的最开始时创建的。它基本上是一个空函数,并且没有明确声明它是可构造的。没有内置的方法可以做到这一点。您可以
try
调用函数new
,然后检查错误或返回true
:但是,该方法不是故障安全的,因为函数可能有副作用,因此在调用
f
之后,您不知道环境处于哪种状态。此外,这只会告诉你一个函数是否 可以 作为构造函数调用,而不是它是否 打算 作为构造函数调用。为此,您必须查看文档或函数的实现。
注意: 永远不应该有理由在生产环境中使用这样的测试。一个函数是否应该用
new
调用应该可以从它的文档中辨别出来。要创建一个真正不可 构造的 函数,您可以使用箭头函数:
根据定义,箭头函数是不可构造的。或者,您可以将函数定义为对象或类的方法。
否则,您可以通过检查它的 ---
this
值来检查是否使用new
(或类似的东西)调用函数,如果是,则抛出错误:当然,由于还有其他方法可以设置
this
的值,因此可能会出现误报。例子