3 回答
TA贡献1786条经验 获得超13个赞
1)您可以检查this.constructor:
function x(y)
{
if (this.constructor == x)
alert('called with new');
else
alert('called as function');
}
2)是的,在new上下文中使用时,返回值只是被丢弃
TA贡献1898条经验 获得超8个赞
注意:现在可以在ES2015及更高版本中使用。请参阅Daniel Weiner的答案。
我认为[ES2015之前]您想要的东西是不可能的。函数内根本没有足够的信息来进行可靠的推断。
查看ECMAScript 3rd Edition规范,new x()调用时所采取的步骤实质上是:
创建一个新对象
将其内部的[[Prototype]]属性分配给的prototype属性 x
x正常调用,将新对象传递给this
如果调用x返回了对象,则返回它,否则返回新对象
对于执行代码而言,有关如何调用该函数的任何有用信息都没有,因此唯一可以在内部进行测试的x就是this值,这就是这里所有答案的作用。如您所见,作为构造函数x调用时,*的新实例与作为函数调用时所传递x的既有实例没有区别,除非您为构造时创建的每个新对象分配一个属性:xthisxx
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构造函数创建的对象”更为简洁
添加回答
举报