Избегайте экспорта синглтона в es6 - PullRequest
0 голосов
/ 04 июля 2018

Как я уже видел, 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'

т.е.: если я изменю экспорт A в B, он также изменится в A и во всех модулях, которые импортируют A Итак, я хотел, чтобы A экспортировал новый экземпляр объекта вместо синглтона, и я сделал это:

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

Это работает, но я подумал, есть ли более чистый способ экспортировать новые экземпляры? Или единственный способ экспортировать ту функцию, которую я должен вызвать в B, чтобы получить мой новый экземпляр?

Я думаю, что тоже могу это сделать, но меня это не убеждает:

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

Спасибо

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Модуль ES оценивается только один раз при первом импорте, это эффективно делает экспорт модулей одиночными.

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

- это фабричная функция, и в этом случае она совершенно действительна, предпочтительнее для объекта с данными, который не имеет наследования и методов.

Класс - подходящая альтернатива (немного менее эффективная, чем фабричная функция, но лучший выбор, если есть методы):

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

Поскольку React используется, можно предположить, что код передается с Babel, поэтому можно использовать предложение поля класса . Они недоступны в ES6 и предоставляют синтаксический сахар для кода конструктора, указанного выше:

export class A {
  user = 'asd';
  asd = 'b';
}
0 голосов
/ 04 июля 2018

Когда модуль загружен, он кэшируется. Таким образом, когда кто-то еще загружает его снова, новый код не запускается. Предыдущий экспорт только что вернулся.

Это работает, но я подумал, есть ли более чистый способ экспорта новых экземпляров? Или единственный способ экспортировать ту функцию, которую я должен вызвать в 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
   }
}

Либо заводская функция, либо функция конструктора будет работать нормально. Если методов нет и вы просто хотите простой объект, то функция фабрики проще. Если есть методы, то класс, вероятно, имеет больше смысла.

...