我在我的文章中使用ES6和Webpack es6-transpiler:http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/
将两个Singleton对象转换为使用ES6类是否有意义?
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 };
这是一个文件ManagerProducts.jsx,它有一个应该从BaseStore扩展的单例。
/**
* 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 };
答案 0 :(得分:67)
这是es6中单例对象的一个非常简单的例子:
let appState = {};
export default appState;
如果您真的想在单身方法中使用课程,我建议不要使用"静态"至少对于一个单身人士来说,至少对于JS而言更令人困惑,而是将类的实例作为单身人士返回,就像这样......
class SomeClassUsedOnlyAsASingleton {
// implementation
}
export default new SomeClassUsedOnlyAsASingleton();
通过这种方式,您仍然可以使用JavaScript提供的所有类别的东西,但它可以减少混淆,因为在JavaScript类中完全不支持IMO静态,因为它在类型语言(如c#或Java)中是它只支持静态方法,除非你伪造它并将它们直接附加到类(在撰写本文时)。
答案 1 :(得分:38)
我认为单身人士(管理他们自己的单身生活的班级)在任何语言中都是不必要的。这并不是说单例生命周期没有用,只是因为我更喜欢类以外的东西管理对象的生命周期,比如DI容器。
话虽这么说,单例模式可以应用于JavaScript类,借用ActionScript中使用的“SingletonEnforcer”模式。在移植使用单例到ES6的现有代码库时,我可以看到想要做这样的事情。
在这种情况下,我们的想法是使用公共静态singleton
getter创建一个私有(通过未公开的符号)静态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;
答案 2 :(得分:11)
I had to do the same so here is a simple and direct way of doing a singleton, curtsy to singleton-classes-in-es6
(original link 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);
Both console.log
calls should print the same cache.time
(Singleton)
答案 3 :(得分:5)
为了创建单例模式,使用带有ES6类的单个实例;
'use strict';
import EventEmitter from 'events';
class Single extends EventEmitter {
constructor() {
this.state = {};
}
getState() {
return this.state;
}
}
export default let single = new Single();
更新:根据@Bergi的解释,下面一个不是有效参数。
这是因为(参考Steven)
您可以在ES6 Singleton找到示例。
注意:此模式在Flux Dispacher中使用
Flux :www.npmjs.com/package/flux
Dispacher示例: github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/AppDispatcher.js#L16
答案 4 :(得分:0)
c.changeGlyph = function(id){
c.right = !c.right
}