正如我所见,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' }))()
谢谢
答案 0 :(得分:3)
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';
}
答案 1 :(得分:1)
加载模块时,将对其进行缓存。因此,当其他人再次加载它时,不会运行任何新代码。以前的出口刚刚返回。
那行得通,但是我在想,是否有一种更干净的方法来导出新实例?还是唯一的方法是导出应该在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
}
}
工厂函数或构造函数都可以正常工作。如果没有方法,而只需要一个普通对象,则工厂函数会更简单。如果有方法,则该类可能更有意义。