Nano Hash - криптовалюты, майнинг, программирование

В чем разница между использованием Object.assign и class/extends?

Я пытаюсь понять, как работает Facebook Flux, глядя на исходный код их пример чата Flux.

Там я увидел это код:

var MessageStore = assign({}, EventEmitter.prototype, {

  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },

  /**
   * @param {function} callback
   */
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },
  ...
}

...

module.exports = MessageStore;

... где assign - это просто полифилл Object.assign из спецификации ES6.

Хм. Будет ли работать этот код с использованием классов и расширений? Будет ли это означать то же самое? Каковы различия и преимущества/недостатки этого подхода?

class MessageStore extends EventEmitter {
    emitChange() {
        this.emit(CHANGE_EVENT);
    }

    addChangeListener(callback) {
        this.on(CHANGE_EVENT, callback);
    }

    ...
}

module.exports = new MessageStore();

Я спрашиваю, потому что, придя из других языков, я интуитивно понимаю class/extends, в то время как наследование на основе прототипов всегда немного непонятно для меня.


  • Object.assign только копирует свойства, наследования нет. 02.01.2016
  • Но код, как я его написал, должен быть равноценным, разве нет? Может быть, за исключением одного класса, который создается и используется только один раз. 02.01.2016
  • Аналогичный, но не идентичный вопрос - stackoverflow.com/questions/29548562/ 02.01.2016
  • Это зависит от того, будет ли изменен EventEmitter.prototype. Если вы хотите наследование, также рассмотрите возможность использования Object.assign(Object.create(EventEmitter.prototype), {...}) 02.01.2016
  • Хм. Оба кода будут работать одинаково, если изменить EventEmitter.prototype, не так ли? 02.01.2016
  • Другой похожий вопрос: stackoverflow.com /вопросы/19965844/ 02.01.2016

Ответы:


1

Вот рабочий код, который вы можете использовать в отношении синтаксиса ES6 и вашей ситуации:

import EventEmitter from 'events';
const CHANGE_EVENT = 'change';

class MessageStore extends EventEmitter {

  constructor() {
    super();
  }

  addChangeListener = (callback) => {
    this.on(CHANGE_EVENT, callback);
  }

  removeChangeListener = (callback) => {
    this.removeListener(CHANGE_EVENT, callback);
  }

  emitChange = () => {
    this.emit(CHANGE_EVENT);
  }

}

Обратите внимание: я предпочитаю литеральный синтаксис функции ES6, потому что он гарантирует, что "this" всегда привязан к контексту окружающего объекта.

Полностью работающий пример магазина ES6 можно найти в сохраняет код в моем приложении Babel React Starter

Это также полезный справочник по классам ES6, который наглядно объясняет, что происходит внутри тела определения класса.

02.01.2016
  • Я не понимаю синтаксиса литерала функции. Как было бы иначе без него? this будет ссылаться на объект, даже если это обычная функция, как в моем вопросе, нет? 02.01.2016
  • @KarelBílek - ты прямо здесь. Однако, в более общем плане, они были укушены и в других случаях, например, с помощью вспомогательных функций, расширяющихся от React.Component. - общий шаблон, который вы видите, - это необходимость явно привязываться к используемой вами функции, например, onPress={this.onLoginPressed.bind(this)}. Однако, если вы объявляете свою функцию onLoginPressed, используя приведенный выше синтаксис, например. onLoginPressed = () =› { console.log('Попытка входа в систему с именем пользователя' + this.state.username); } тогда вам больше не нужно привязывать явно. например. просто используйте onPress={this.onLoginPressed} в результате, предпочитайте этот синтаксис, так что не сомневайтесь. 03.01.2016

  • 2

    расширение класса*. Вы расширяете общий класс, что иногда является именно тем, что вам нужно, например. button расширяет domElement, но button не должен расширять EventEmitter, потому что у них нет ничего общего.

    Object.assign: с помощью Object.assign вы «примешиваете» новую функциональность к целевому объекту, например. Store может смешивать EventEmitter. В Java вы бы использовали Store implements EventEmitter, что немного более понятно.

    27.06.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..