Javascript 将 Singleton JS 对象转换为使用 ES6 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26205565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting Singleton JS objects to use ES6 classes
提问by justingordon
I'm using ES6 with the Webpack es6-transpiler per my article here: http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/
根据我的文章,我将 ES6 与 Webpack es6-transpiler 一起使用:http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-现有轨道项目/
Does it make any sense to convert two Singleton objects to use ES6 Classes?
将两个 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 };
This is file ManagerProducts.jsx that has a singleton that should extend from 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 };
回答by Jason Sebring
No. Makes no sense.
不。没有意义。
Here's a really simple example of a singleton object in es6:
这是 es6 中单例对象的一个非常简单的示例:
let appState = {};
export default appState;
If you really want to use a class in your singleton approach, I would recommend against using "static" as it more confusing than good for a singleton at least for JS and instead return the instance of the class as a singleton like so...
如果你真的想在你的单例方法中使用一个类,我建议不要使用“静态”,因为它至少对于 JS 来说对于单例来说更令人困惑而不是好,而是将类的实例作为单例返回,就像这样......
class SomeClassUsedOnlyAsASingleton {
// implementation
}
export default new SomeClassUsedOnlyAsASingleton();
This way you can still use all the class things you like that JavaScript offers but it will reduce the confusion as IMO static isn't fully supported in JavaScript classes anyway as it is in typed languages such as c# or Java as it only supports static methods unless you just fake it and attach them directly to a class (at the time of this writing).
通过这种方式,您仍然可以使用 JavaScript 提供的所有您喜欢的类,但它会减少混淆,因为无论如何 JavaScript 类并不完全支持 IMO 静态,因为它在类型语言(如 c# 或 Java)中仅支持静态方法除非你只是伪造它并将它们直接附加到一个类(在撰写本文时)。
回答by Brian Genisio
I'd argue that singletons (classes that manage their own singleton lifetime) are unnecessary in any language. That is not to say that singleton lifetime is not useful, just that I prefer that something other than the class manage the lifetime of an object, like a DI container.
我认为在任何语言中都不需要单例(管理自己的单例生命周期的类)。这并不是说单例生命周期没有用,只是我更喜欢类以外的东西来管理对象的生命周期,比如 DI 容器。
That being said, the singleton pattern CAN be applied to JavaScript classes, borrowing the "SingletonEnforcer" pattern that was used in ActionScript. I can see wanting to do something like this when porting an existing code base that uses singletons into ES6.
也就是说,单例模式可以应用于 JavaScript 类,借用 ActionScript 中使用的“SingletonEnforcer”模式。在将使用单例的现有代码库移植到 ES6 时,我可以看到想要做这样的事情。
In this case, the idea is that you make a private (via an un exposed Symbol) static singletoninstance, with a public static instancegetter. You then restrict the constructor to something that has access to a special singletonEnforcersymbol that is not exposed outside of the module. That way, the constructor fails if anyone other than the singleton tries to "new" it up. It would look something like this:
在这种情况下,想法是singleton使用公共静态instancegetter创建一个私有(通过未公开的 Symbol)静态实例。然后将构造函数限制为可以访问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
Then you can use it like any other singleton:
然后你可以像任何其他单例一样使用它:
import SingletonTest from 'singleton-test';
const instance = SingletonTest.instance;
回答by AdrianD
I had to do the same so here is a simple and direct way of doing a singleton, curtsy to singleton-classes-in-es6
我必须做同样的事情,所以这里有一个简单而直接的方法来做一个单身人士,屈膝礼在 es6 中的单身人士类
(original link http://amanvirk.me/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);
Both console.logcalls should print the same cache.time(Singleton)
两个console.log调用都应该打印相同的cache.time(单例)
回答by Milan Karunarathne
In order to create Singleton patternuse a single instance with ES6 classes;
为了创建单例模式,使用带有 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: According to @Bergi explanation, below one is not a valid argument.
更新:根据@Bergi 的解释,下面的一个不是有效的论点。
This works because of (refer to Steven)
这是因为(参考Steven)
You can find an example here ES6 Singleton.
你可以在这里找到一个例子ES6 Singleton。
Note: This pattern is using in Flux Dispacher
注意:此模式在 Flux Dispacher 中使用
Flux: www.npmjs.com/package/flux
通量:www.npmjs.com/package/flux
Dispacher Example: github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/AppDispatcher.js#L16
调度程序示例:github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/AppDispatcher.js#L16
回答by M. Hamza Rajput
Singleton class
单例类
class SingletonClass {
constructor( name = "", age = 0 ) {
if ( !this.constructor.instance ) {
this.constructor.instance = this;
this.name = name;
this.age = age;
}
return this.constructor.instance;
}
getName() {
return this.name;
}
getAge() {
return this.age;
}
}
const instanceOne = new SingletonClass( "One", 25 );
const instanceTwo = new SingletonClass( "Two", 44 );
console.log( `Name of instanceOne is "${instanceOne.getName()}"` );
console.log( `Name of instanceTwo is "${instanceTwo.getName()}"` );

