esclip快捷键构造函数,如何检测一个函数是否被称为构造函数?

本文探讨了如何在JavaScript中检测一个函数是被用作构造函数还是普通函数调用的方法。考虑到ES2015之前的限制,文章提供了一种通过检查this上下文的方法,并探讨了其局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a function:

function x(arg) { return 30; }

You can call it two ways:

result = x(4);

result = new x(4);

The first returns 30, the second returns an object.

How can you detect which way the function was called inside the function itself?

Whatever your solution is, it must work with the following invocation as well:

var Z = new x();

Z.lolol = x;

Z.lolol();

All the solutions currently think the Z.lolol() is calling it as a constructor.

解决方案

NOTE: This is now possible in ES2015 and later. See Daniel Weiner's answer.

I don't think what you want is possible [prior to ES2015]. There simply isn't enough information available within the function to make a reliable inference.

Looking at the ECMAScript 3rd edition spec, the steps taken when new x() is called are essentially:

Create a new object

Assign its internal [[Prototype]] property to the prototype property of x

Call x as normal, passing it the new object as this

If the call to x returned an object, return it, otherwise return the new object

Nothing useful about how the function was called is made available to the executing code, so the only thing it's possible to test inside x is the this value, which is what all the answers here are doing. As you've observed, a new instance of* x when calling x as a constructor is indistinguishable from a pre-existing instance of x passed as this when calling x as a function, unless you assign a property to every new object created by x as it is constructed:

function x(y) {

var isConstructor = false;

if (this instanceof x //

// except in in EcmaScript 5 strict mode.

&& !this.__previouslyConstructedByX) {

isConstructor = true;

this.__previouslyConstructedByX = true;

}

alert(isConstructor);

}

Obviously this is not ideal, since you now have an extra useless property on every object constructed by x that could be overwritten, but I think it's the best you can do.

(*) "instance of" is an inaccurate term but is close enough, and more concise than "object that has been created by calling x as a constructor"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值