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

给定一个功能:


function x(arg) { return 30; }

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


result = x(4);

result = new x(4);

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


您如何检测在函数本身内部调用该函数的方式?


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


var Z = new x(); 

Z.lolol = x; 

Z.lolol();

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


MMTTMM
浏览 851回答 3
3回答

开满天机

1)您可以检查this.constructor:function x(y){    if (this.constructor == x)        alert('called with new');    else         alert('called as function');}2)是的,在new上下文中使用时,返回值只是被丢弃

汪汪一只猫

注意:现在可以在ES2015及更高版本中使用。请参阅Daniel Weiner的答案。我认为[ES2015之前]您想要的东西是不可能的。函数内根本没有足够的信息来进行可靠的推断。查看ECMAScript 3rd Edition规范,new x()调用时所采取的步骤实质上是:创建一个新对象将其内部的[[Prototype]]属性分配给的prototype属性 xx正常调用,将新对象传递给this如果调用x返回了对象,则返回它,否则返回新对象对于执行代码而言,有关如何调用该函数的任何有用信息都没有,因此唯一可以在内部进行测试的x就是this值,这就是这里所有答案的作用。如您所见,作为构造函数x调用时,*的新实例与作为函数调用时所传递x的既有实例没有区别,除非您为构造时创建的每个新对象分配一个属性:xthisxxfunction x(y) {&nbsp; &nbsp; var isConstructor = false;&nbsp; &nbsp; if (this instanceof x // <- You could use arguments.callee instead of x here,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // except in in EcmaScript 5 strict mode.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && !this.__previouslyConstructedByX) {&nbsp; &nbsp; &nbsp; &nbsp; isConstructor = true;&nbsp; &nbsp; &nbsp; &nbsp; this.__previouslyConstructedByX = true;&nbsp; &nbsp; }&nbsp; &nbsp; alert(isConstructor);}显然,这并不理想,因为您现在对每个x由此构造的对象都拥有一个额外的无用属性,但该属性可能会被覆盖,但我认为这是您可以做的最好的事情。(*) “ instance of”是一个不准确的术语,但足够接近,并且比“通过调用x构造函数创建的对象”更为简洁
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript