用JavaScript实现单例模式的最简单/最干净的方法是什么?
当前回答
我需要几个单人间:
延迟初始化 初始参数
这就是我想到的:
createSingleton ('a', 'add', [1, 2]);
console.log(a);
function createSingleton (name, construct, args) {
window[name] = {};
window[construct].apply(window[name], args);
window[construct] = null;
}
function add (a, b) {
this.a = a;
this.b = b;
this.sum = a + b;
}
args必须是Array,所以如果你有空变量,只需要传入[] 我在函数中使用了window对象,但我本可以传入一个参数来创建自己的作用域 name和构造参数只是字符串,以便window[]工作,但有一些简单的类型检查,window.name和window.name。构造也是可能的。
其他回答
另一种方法-只是确保类不能再新的。
这样,您就可以使用instanceof op。此外,您还可以使用原型链来继承类。这是一个普通的课程,但是你不能去学。如果你想获取实例,只需使用getInstance:
function CA()
{
if(CA.instance)
{
throw new Error('can not new this class');
}
else
{
CA.instance = this;
}
}
/**
* @protected
* @static
* @type {CA}
*/
CA.instance = null;
/* @static */
CA.getInstance = function()
{
return CA.instance;
}
CA.prototype =
/** @lends CA# */
{
func: function(){console.log('the func');}
}
// Initialise the instance
new CA();
// Test here
var c = CA.getInstance()
c.func();
console.assert(c instanceof CA)
// This will fail
var b = new CA();
如果不想公开实例成员,只需将其放入闭包中。
模块模式:“更具可读性的风格”。您可以很容易地看到哪些方法是公共的,哪些是私有的
var module = (function(_name){
/* Local Methods & Values */
var _local = {
name : _name,
flags : {
init : false
}
}
function init(){
_local.flags.init = true;
}
function imaprivatemethod(){
alert("Hi, I'm a private method");
}
/* Public Methods & variables */
var $r = {}; // This object will hold all public methods.
$r.methdo1 = function(){
console.log("method1 calls it");
}
$r.method2 = function(){
imaprivatemethod(); // Calling private method
}
$r.init = function(){
inti(); // Making 'init' public in case you want to init manually and not automatically
}
init(); // Automatically calling the init method
return $r; // Returning all public methods
})("module");
现在你可以使用公共方法,比如
module.method2 ();// ->我正在调用一个私有方法超过一个公共方法警报(“嗨,我是一个私有方法”)
http://jsfiddle.net/ncubica/xMwS9/
class Singelton {
static #instance;
#testValue;
constructor() {
if (Singelton.#instance instanceof Singelton) {
return Singelton.#instance;
}
Singelton.#instance = this;
return Singelton.#instance;
}
get testValue() {
return this.#testValue;
}
set testValue(value) {
this.#testValue = value;
}
}
测试:
let x = new Singelton();
x.testValue = 123;
let y = new Singelton();
console.log({isSingelton: x === y, testValueFromY: y.testValue});
你没说"在浏览器里"否则,你可以使用Node.js模块。这些对于每个require调用都是相同的。基本的例子:
foo.js的内容: Const circle = require('./circle.js'); console.log('半径为4的圆的面积为${circle.area(4)} '); circle.js的内容: const PI = Math.PI; 出口。area = (r) => PI * r * r; 出口。周长= (r) => 2 * PI * r;
注意,您不能访问圆。PI,因为它没有导出。
虽然这在浏览器中不起作用,但它简单而干净。
这就是我如何使用ES6特性实现单例模式。是的,我知道这看起来不像面向对象的方法,但我发现这个方法很容易实现,而且是一种干净的实现方式。
const Singleton = (() => {
var _instance = !_instance && new Object('Object created....');
return () => _instance;
})();
//************************************************************************
var instance1 = Singleton();
var instance2 = Singleton();
console.log(instance1 === instance2); // true
推荐文章
- Babel 6改变了它导出默认值的方式
- 如何配置历史记录?
- ES6模板文字可以在运行时被替换(或重用)吗?
- [Vue警告]:找不到元素
- 可以在setInterval()内部调用clearInterval()吗?
- AngularJS控制器的生命周期是什么?
- 无法读取未定义的属性“msie”- jQuery工具
- 我的蛋蛋怎么不见了?
- JavaScript中的排列?
- JavaScript中有睡眠/暂停/等待功能吗?
- 如何禁用文本选择使用jQuery?
- 如何停止事件冒泡复选框点击
- 如何在PHP中截断字符串最接近于一定数量的字符?
- 向对象数组添加属性
- 如何在Redux应用程序中动态加载代码分割的减速器?