web-dev-qa-db-ja.com

ES6クラスを使用するためのシングルトンJSオブジェクトの変換

私はここで私の記事ごとにWebpack es6-transpilerでES6を使用しています: http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler- into-an-existing-Rails-project /

ES6クラスを使用するために2つのシングルトンオブジェクトを変換することは意味がありますか?

import { CHANGE_EVENT } from "../constants/Constants";

var EventEmitter = require('events').EventEmitter;
var merge = require('react/lib/merge');

var _flash = null;

var BaseStore = merge(EventEmitter.prototype, {

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

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

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

  getFlash: function() {
    return _flash;
  },

  setFlash: function(flash) {
    _flash = flash;
  }
});

export { BaseStore };

これは、BaseStoreから拡張するシングルトンを含むManagerProducts.jsxファイルです。

/**
 * Client side store of the manager_product resource
 */
import { BaseStore } from "./BaseStore";
import { AppDispatcher } from '../dispatcher/AppDispatcher';
import { ActionTypes } from '../constants/Constants';
import { WebAPIUtils } from '../utils/WebAPIUtils';
import { Util } from "../utils/Util";
var merge = require('react/lib/merge');

var _managerProducts = [];

var receiveAllDataError = function(action) {
  console.log("receiveAllDataError %j", action);
  WebAPIUtils.logAjaxError(action.xhr, action.status, action.err);
};

var ManagerProductStore = merge(BaseStore, {
  getAll: function() {
    return _managerProducts;
  }
});

var receiveAllDataSuccess = function(action) {
  _managerProducts = action.data.managerProducts;
  //ManagerProductStore.setFlash({ message: "Manager Product data loaded"});
};


ManagerProductStore.dispatchToken = AppDispatcher.register(function(payload) {
  var action = payload.action;
  if (Util.blank(action.type)) { throw `Invalid action, payload ${JSON.stringify(payload)}`; }

  switch(action.type) {
    case ActionTypes.RECEIVE_ALL_DATA_SUCCESS:
      receiveAllDataSuccess(action);
      break;
    case ActionTypes.RECEIVE_ALL_DATA_ERROR:
      receiveAllDataError(action);
      break;
    default:
      return true;
  }
  ManagerProductStore.emitChange();
  return true;
});

export { ManagerProductStore };
24
justingordon

私は、シングルトン(シングルトンの寿命を管理するクラス)はどの言語でも不要であると主張します。それは、シングルトンのライフタイムが役に立たないということではなく、クラス以外の何かがDIコンテナのようなオブジェクトのライフタイムを管理することを好むということだけです。

つまり、シングルトンパターンはJavaScriptクラスに適用でき、ActionScriptで使用された「SingletonEnforcer」パターンを借用できます。シングルトンを使用する既存のコードベースをES6に移植するときに、このようなことをしたいと思うことがあります。

この場合、パブリックの静的singletonゲッターを使用して、プライベート(非公開シンボルを介して)静的instanceインスタンスを作成するという考え方です。次に、モジュールの外部に公開されていない特別なsingletonEnforcerシンボルにアクセスできるものにコンストラクターを制限します。そのようにして、シングルトン以外の誰かがそれを「新規」にしようとすると、コンストラクターは失敗します。次のようになります。

const singleton = Symbol();
const singletonEnforcer = Symbol()

class SingletonTest {

  constructor(enforcer) {
    if(enforcer != singletonEnforcer) throw "Cannot construct singleton";
  }

  static get instance() {
    if(!this[singleton]) {
      this[singleton] = new SingletonTest(singletonEnforcer);
    }
    return this[singleton];
  }
}

export default SingletonTest

その後、他のシングルトンと同様に使用できます。

import SingletonTest from 'singleton-test';
const instance = SingletonTest.instance;
38
Brian Genisio

いいえ、意味がありません。

Es6のシングルトンオブジェクトの非常に簡単な例を次に示します。

let appState = {};
export default appState;

シングルトンアプローチでクラスを本当に使用したい場合は、少なくともJSのシングルトンに適しているよりも混乱を招くので、代わりにクラスのインスタンスをシングルトンとして返すため、「静的」を使用しないことをお勧めします。

class SomeClassUsedOnlyAsASingleton {
  // implementation
}

export default new SomeClassUsedOnlyAsASingleton();

この方法では、JavaScriptが提供するすべてのクラスを引き続き使用できますが、c#やJavaなどの型付き言語ではIMO静的がJavaScriptクラスで完全にサポートされないため、混乱を軽減できます。静的メソッドのみをサポートします(偽装してクラスに直接アタッチする場合を除きます)(執筆時点)。

67
Jason Sebring

私は同じことをしなければならなかったので、ここではシングルトンを行う簡単で直接的な方法であり、 singleton-classes-in-es6

(元のリンク http://amanvirk.me/singleton-classes-in-es6/

let instance = null;

class Cache{  
    constructor() {
        if(!instance){
              instance = this;
        }

        // to test whether we have singleton or not
        this.time = new Date()

        return instance;
      }
}


let cache = new Cache()
console.log(cache.time);

setTimeout(function(){
  let cache = new Cache();
  console.log(cache.time);
},4000);

両方 console.log呼び出しは同じcache.time(シングルトン)

11
AdrianD

のために シングルトンパターンを作成する ES6クラスで単一のインスタンスを使用します。

'use strict';

import EventEmitter from 'events';

class Single extends EventEmitter {
    constructor() {
        this.state = {};
    }

    getState() {
        return this.state;
    }

}

export default let single = new Single();

Update:@Bergiの説明によると、以下のものは有効な引数ではありません。

これは、( Steven を参照)のために機能します

> CommonJS +ブラウザーの実装を正しく理解している場合、モジュールの出力はキャッシュされるため、デフォルトの新しいMyClass()をエクスポートすると、シングルトンとして動作するものになります(このクラスのインスタンスは実行しているenvに応じてプロセス/クライアント)。

ここに例を見つけることができます ES6シングルトン

:このパターンはFlux Dispacherで使用されています

Flux:www.npmjs.com/package/flux

ディスパッチャーの例github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/ AppDispatcher.js#L16

5