【问题标题】:Avoid exporting singleton in es6避免在 es6 中导出单例
【发布时间】:2018-07-04 19:35:22
【问题描述】:

正如我所见,ES6 为对象字面量导出单例:

// module A
export const singleton = {
  user: 'a',
  asd: 'b'
}

setTimeout(() => console.log(singleton.user), 5000) // 'asd'

// module B
import { singleton } from './A'
singleton.user = 'asd'

ie:如果我更改 B 中的 A 导出,它也会在 A 和所有导入 A 的模块中更改 因此,我希望 A 导出对象的新实例而不是单例,我这样做了:

// module A
export const getObject = () => ({ user: 'asd', asd: 'b' })

这行得通,但我在想,有没有更简洁的方法来导出新实例?或者唯一的方法是导出我应该在 B 中调用的函数来获取我的新实例?

我想我也可以做到,但并不能说服我:

// module A
export const getObject = (() => ({ user: 'asd', asd: 'b' }))()

谢谢

【问题讨论】:

  • 使用工厂函数有什么问题?
  • freezing singleton 呢?
  • @sp00m - op 每次都想要一个新的对象实例。冻结并没有做到这一点。
  • @LucasJanon 仅供参考,“freeze”的过去分词是“frozen”,所以你的变量应该命名为frozenObj ;)
  • 哈哈,看来我应该多看迪斯尼电影,不要再考虑单例来改进我的变量命名了:p

标签: javascript reactjs ecmascript-6 es6-modules


【解决方案1】:

ES 模块在第一次导入时只评估一次,这有效地使模块导出单例。

export const getObject = () => ({ user: 'asd', asd: 'b' })

是工厂函数,在这种情况下完全有效,它更适合没有继承和方法的纯数据对象。

类是一个合适的替代方案(比工厂函数效率稍低,但如果有方法则更好):

export class A {
  constructor() {
    this.user =  'asd';
    this.asd = 'b';
  }
}

由于使用了 React,因此可以安全地假设代码使用 Babel 进行了转译,因此可以使用 class fields 提案。它们在 ES6 中不可用,并为上面列出的构造函数代码提供语法糖:

export class A {
  user = 'asd';
  asd = 'b';
}

【讨论】:

    【解决方案2】:

    当一个模块被加载时,它会被缓存。因此,当其他人再次加载它时,不会运行新代码。之前的导出只是返回。

    这行得通,但我在想,有没有更简洁的方法来导出新实例?或者唯一的方法是导出我应该在 B 中调用的函数来获取我的新实例?

    如果您每次都想要一个新实例,则必须导出一个函数,您可以调用该函数来获取一个新实例。没有其他方法,因为加载之前加载的模块不会运行任何额外的代码——它只是返回之前缓存的导出。

    您可以导出工厂函数(如您的示例中):

    export const myFactory = function() {
       return { user: 'asd', asd: 'b' };
    }
    

    或者您可以导出一个构造函数(调用者将使用new 调用该函数以获取新对象)。

    export class myObj {
       constructor() {
           this.user = 'asd';
           this.asd = 'b';
       }
       checkUser() {
           // some code here that operates on instance data
       }
    }
    

    工厂函数或构造函数都可以正常工作。如果没有方法而你只想要一个普通的对象,那么工厂函数就更简单了。如果有方法,那么类可能更有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      相关资源
      最近更新 更多