如何检测一个函数是否被称为构造函数?

给定一个功能:

function x(arg) { return 30; }

您可以用两种方式来称呼它:

result = x(4);

result = new x(4);

第一个返回30,第二个返回一个对象。

您如何检测 调用 ?

无论您采用哪种解决方案,它都必须与以下调用一起使用:

var Z = new x(); 

Z.lolol = x;

Z.lolol();

当前所有解决方案都认为将该Z.lolol()方法称为构造函数

回答:

我认为[ES2015之前]您想要的东西是不可能的。函数内根本没有足够的信息来进行可靠的推断。

查看ECMAScript 3rd Edition规范,new x()调用时所采取的步骤实质上是:

  • 创建一个新对象
  • 将其内部的[[Prototype]]属性分配给的prototype属性 x
  • x正常调用,将新对象传递给this
  • 如果调用x返回了对象,则返回它,否则返回新对象

对于执行该代码而言,没有什么有用的关于函数调用的方法,因此,唯一可以在内部进行测试的x就是this值,这就是所有答案的作用。正如您所观察到的,的新实例x时调用x的构造函数是从预先存在的实例不可区分的x方式是:传递this时调用x一个函数,

除非* 你指定一个属性被创建的每个新的对象x,因为它构造:

function x(y) {

var isConstructor = false;

if (this instanceof x // <- You could use arguments.callee instead of x here,

// except in in EcmaScript 5 strict mode.

&& !this.__previouslyConstructedByX) {

isConstructor = true;

this.__previouslyConstructedByX = true;

}

alert(isConstructor);

}

显然,这并不理想,因为您现在x可以覆盖每个由此构造的对象的多余的属性,但是我认为这是您可以做的最好的事情。

“ instance of”是一个不准确的术语,但足够接近,并且比“ x作为构造函数调用而创建的对象”更为简洁

以上是 如何检测一个函数是否被称为构造函数? 的全部内容, 来源链接: utcz.com/qa/425462.html

回到顶部