为了账号安全,请及时绑定邮箱和手机立即绑定

ES6:没有new关键字的调用类构造函数

ES6:没有new关键字的调用类构造函数

温温酱 2019-08-28 09:25:46
ES6:没有new关键字的调用类构造函数给出一个简单的类class Foo {   constructor(x) {     if (!(this instanceof Foo)) return new Foo(x);     this.x = x;   }   hello() {     return `hello ${this.x}`;   }}是否可以在没有new关键字的情况下调用类构造函数?用法应该允许(new Foo("world")).hello(); // "hello world"要么Foo("world").hello();       // "hello world"但后者失败了Cannot call a class as a function
查看完整描述

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) };


查看完整回答
反对 回复 2019-08-28
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

正如其他人已经指出的那样,ES2015规范严格规定这样的调用应该抛出TypeError,但同时它提供了可用于实现所需结果的功能,即Proxies

代理允许我们虚拟化对象的概念。例如,它们可用于更改特定对象的某些行为,而不会影响其他任何内容。

在您的特定使用案例class FooFunction 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类的可行解决方案。


查看完整回答
反对 回复 2019-08-28
  • 3 回答
  • 0 关注
  • 657 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号