【问题标题】:How to instantiate an anonymous es6 class within itself如何在自身内部实例化一个匿名 es6 类
【发布时间】:2016-04-12 20:23:40
【问题描述】:

假设我正在解析一棵树,其中一个节点可以将另一个节点实例化为子节点。当类被命名时,这很容易:

class Node {
    parseLeaves( leaves ) {
        _.each( 
            leaves,
            ( leaf ) => {
                this.leaves.push( new Node( leaf ) );
            }
        );
    }
}

但是如果类在没有首先命名的情况下被导出怎么办?如何确定班级?即

export default class {
    parseLeaves( leaves ) {
        _.each( 
            leaves,
            ( leaf ) => {
                this.leaves.push( new ???( leaf ) ); 
            }
        );
    }
}

【问题讨论】:

  • 你试过用exports.default代替???
  • @AdnanUmer 就是这样!如果您想提交作为答案,我会选择它
  • 我在下面描述了一个稍微好一点但仍然很糟糕的想法。请在将其放入您的代码之前,先看看 =)

标签: javascript ecmascript-6 babeljs


【解决方案1】:

可以按照你的要求去做,但是我不建议这样做

javascript 中的所有对象都有一个constructor 属性,它指向它们的类。我所说的“对象”是指除了nullundefined 之外的所有东西都是如此。

export default class {
  createAnotherInstance() {
    return new this.constructor()
  }
}

这不是一个好主意,至少有两个重要原因:

  1. 未命名的类使调试更加困难。通过类的堆栈跟踪将缺少有用的名称。检查您的对象的人不会知道他们在处理什么。如果您的所有类都遵循这种模式,那么包含意外类型的变量将很难检测到。

  2. 当您可能需要基类时,调用createAnotherInstance 的子类将返回子类实例(它们自己的constructor)。即使您希望这样做,这种方法也使它看起来像一个意外。三天后你会忘记,它可能会回来咬你。

如果我是你,我会为班级命名。名字很好。未命名的东西是模棱两可的,只能在计算机或程序员没有其他可能解释的情况下使用。

export default class Node { ... }

【讨论】:

  • 积分。尽管在这些方面这并不比使用 ES5 代码差。
【解决方案2】:

如果我深入研究 ES6 编译器生成的 JS,export default 的值存储为exports.default

所以,您仍然可以使用 exports.default 引用那个未命名的类

export default class {
    parseLeaves( leaves ) {
        _.each( 
            leaves,
            ( leaf ) => {
                this.leaves.push( new exports.default( leaf ) ); 
            }
        );
    }
}

【讨论】:

  • 这利用了 ES6 编译器将这些编译为 CommonJS 格式的事实。这不适用于原生 ES6。
  • 供将来参考,虽然这是“正确”的答案,但@slezica 提出的批评是有效的。
  • 请不要混用模块系统。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2014-01-03
相关资源
最近更新 更多