gpt4 book ai didi

javascript - 如何检测函数是否被称为构造函数?

转载 作者:IT王子 更新时间:2023-10-29 02:41:23 25 4
gpt4 key购买 nike

给定一个函数:

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 及更高版本中是可能的。参见 Daniel Weiner's answer .

我不认为你想要的是可能的 [在 ES2015 之前]。函数中根本没有足够的可用信息来做出可靠的推断。

查看 ECMAScript 第 3 版规范,调用 new x() 时采取的步骤基本上是:

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

关于函数调用方式的任何有用信息都无法提供给正在执行的代码,因此在 x 中唯一可以测试的是 this 值,它是这里所有的答案都在做什么。正如您所观察到的,当调用 x 作为构造函数时,* x 的新实例与传递给 x 的预先存在的实例没有区别作为函数调用 x 时的 this除非您将属性分配给 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 构造的每个对象上都有一个额外的无用属性可以被覆盖,但我认为这是您能做的最好的事情。

(*) “的实例”是一个不准确的术语,但足够接近,并且比“通过调用 x 作为构造函数创建的对象”更简洁

关于javascript - 如何检测函数是否被称为构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/367768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com