3 回答

TA贡献1757条经验 获得超7个赞
类有一个“类体”,它是一个构造函数。
如果使用内部constructor()
函数,那么该函数也将是同一个类体,并且将在调用类时调用,因此类始终是构造函数。
构造函数需要使用的new
运算符来创建一个新的实例,因此调用类没有new
一个错误操作的结果,因为它需要的类的构造函数来创建一个新的实例。
错误消息也非常具体,而且正确
TypeError:没有'new'时不能调用类构造函数
你可以;
使用常规函数而不是类1。
总是打电话给班级
new
。在包装常规函数中调用类,总是使用
new
,这样你就可以获得类的好处,但是使用和不使用new
运算符2仍然可以调用包装函数。
1)
function Foo(x) { if (!(this instanceof Foo)) return new Foo(x); this.x = x; this.hello = function() { return this.x; }}
2)
class Foo { constructor(x) { this.x = x; } hello() { return `hello ${this.x}`; }}var _old = Foo;Foo = function(...args) { return new _old(...args) };

TA贡献2036条经验 获得超8个赞
正如其他人已经指出的那样,ES2015规范严格规定这样的调用应该抛出TypeError,但同时它提供了可用于实现所需结果的功能,即Proxies。
代理允许我们虚拟化对象的概念。例如,它们可用于更改特定对象的某些行为,而不会影响其他任何内容。
在您的特定使用案例class Foo
是Function object
可以称之为-这通常意味着该函数的身体将被执行。但这可以通过以下方式改变Proxy
:
const _Foo = new Proxy(Foo, { // target = Foo apply (target, thisArg, argumentsList) { return new target(...argumentsList); }});_Foo("world").hello(); const f = _Foo("world");f instanceof Foo; // truef instanceof _Foo; // true
(注意,_Foo
现在是您要公开的类,因此标识符可能应该是另一种方式)
如果由支持Proxies的浏览器运行,则调用_Foo(...)
现在将执行apply
陷阱功能而不是orignal构造函数。
同时,这个“新” _Foo
类与原始类无法区分Foo
(除了能够将其称为正常函数)。类似地,你可以告诉使用Foo
和创建的对象没有区别_Foo
。
最大的缺点是它无法被发现或被pollyfilled,但它仍然是未来可能在JS中应用Scala类的可行解决方案。
添加回答
举报