创建新类和使用export const的区别

27

设置:

  • BabelJS(es2015,react,stage-1)
  • Webpack
  • React / redux

对 CommonJS 和 ES6 不熟悉。我知道对象实例和方法的静态容器之间的区别,但我不确定当它们分离到模块中时它们的行为如何。 所以我想知道返回实例和返回静态方法容器之间有什么区别(这种模式是否有效?):

// StateParser.js

class StateParser {
    constructor() {
     }

     method1() {
        ...
     }

}

export default new StateParser()

并导出const方法:

// StateParser.js

let state = {
}

export const method1 = () => { ... }
  1. 方法A:每次导入时都会有一个新的实例吗?
  2. 方法B:其中一个好处是能够使用对象解构吗:

  3. import { method1 } from '../utils/StateParser.js';
    

    然后像本地存在一样使用method1?

  4. 方法A:其中一个好处是能够在构造函数中初始化状态吗?

基本上我不确定何时在实用类中使用哪个,希望您的建议。

2个回答

32

每次导入A时是否会创建新实例?

不会,模块只被求值一次。

B的好处之一是可以使用对象解构,然后将method1用作本地存在的方法吗?

是的,虽然它不叫“解构”。它们是模块的命名导入(或模块的命名导出),它们不会嵌套并使用不同的语法进行别名。

A的好处之一是可以在构造函数中初始化状态吗?

不是。您也可以直接在模块范围内初始化模块状态,无需构造函数。

但是,如果实例中有状态,则最好使用可以多次实例化的类。为此,当然需要导出类本身,而不是实例。

export default new … 模式是否有效?

不行,这是一个反面教材,原因如上所述。鉴于该类在其他地方没有使用,它与匿名类反模式非常相似。默认导出对象比导出多个命名导出要好得多


这个与匿名类的工作方式不同,正如你所指出的那样,import A 只会被评估一次,它不是一个技术上的单例实例吗? - thisismydesign
@thisismydesign 嗯,它在模块外没有名称 - 你不能导入类本身 - 所以你可以称之为匿名 :-) 是的,它是一个单例,这不仅是一个反模式(全局状态),而且还是一个反模式,因为使用 class 语法来创建单例是不被鼓励的。 - Bergi
我明白为什么它可以被视为匿名的,但是你提供的关于匿名类的问题在这里并不适用。你说得对,这个类定义是一个反模式。然而,我认为全局状态的论点高度取决于上下文(OP正在询问React),不确定为什么类语法也被反对。 - thisismydesign
@thisismydesign 因为应该使用一个简单的对象字面量,而不是。 - Bergi
这并不是一个单例,根据定义。这也在那个线程中详细讨论过。公平地说,导出实例的这种方法也不严格符合单例模式。 - thisismydesign

5

我们不建议导出一个评估结果(例如new StateParser()),因为有几个原因。

在这种情况下,模块仅导出一次评估结果(也由@Bergi提到)。这很少是期望的结果,但如果是,则应改用单例模式。某些ES6模块的好处会丢失(tree-shaking更快速地访问导入),它使导入变慢,并使它们产生副作用,而这些副作用应该在调用时发生。我也认为这是一个反模式,可以通过导出函数或类来避免缺点。

export default StateParser与导出常量方法进行比较更有意义。

另请参见:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接