用JavaScript实现单例模式的最简单/最干净的方法是什么?
当前回答
对我来说,最干净的方法是:
const singleton = new class {
name = "foo"
constructor() {
console.log(`Singleton ${this.name} constructed`)
}
}
使用这种语法,您可以确定您的单例是并且将保持惟一的。您还可以享受类语法的甜蜜,并按预期使用它。
(注意,类字段需要节点v12+或现代浏览器。)
其他回答
你可以用下面这个例子中的TypeScript装饰器来做:
class YourClass {
@Singleton static singleton() {}
}
function Singleton(target, name, descriptor) {
var instance;
descriptor.value = () => {
if(!instance) instance = new target;
return instance;
};
}
然后你像这样使用你的单例:
var myInstance = YourClass.singleton();
在撰写本文时,JavaScript引擎中还没有装饰器。你需要确保你的JavaScript运行时实际上启用了装饰器,或者使用像Babel和TypeScript这样的编译器。
还要注意的是,单例实例是“惰性”创建的,也就是说,只有当你第一次使用它时才会创建它。
最明确的答案应该是Addy Osmani所著的《学习JavaScript设计模式》一书。
var mySingleton = (function () { // Instance stores a reference to the singleton var instance; function init() { // Singleton // Private methods and variables function privateMethod(){ console.log( "I am private" ); } var privateVariable = "I'm also private"; var privateRandomNumber = Math.random(); return { // Public methods and variables publicMethod: function () { console.log( "The public can see me!" ); }, publicProperty: "I am also public", getRandomNumber: function() { return privateRandomNumber; } }; }; return { // Get the singleton instance if one exists // or create one if it doesn't getInstance: function () { if ( !instance ) { instance = init(); } return instance; } }; })();
function Once() {
return this.constructor.instance || (this.constructor.instance = this);
}
function Application(name) {
let app = Once.call(this);
app.name = name;
return app;
}
如果你在上课:
class Once {
constructor() {
return this.constructor.instance || (this.constructor.instance = this);
}
}
class Application extends Once {
constructor(name) {
super();
this.name = name;
}
}
测试:
console.log(new Once() === new Once());
let app1 = new Application('Foobar');
let app2 = new Application('Barfoo');
console.log(app1 === app2);
console.log(app1.name); // Barfoo
JavaScript中的单例是使用模块模式和闭包实现的。
下面的代码是不言自明的
// Singleton example.
var singleton = (function() {
var instance;
function init() {
var privateVar1 = "this is a private variable";
var privateVar2 = "another var";
function pubMethod() {
// Accessing private variables from inside.
console.log(this.privateVar1);
console.log(this.privateVar2);
console.log("inside of a public method");
};
}
function getInstance() {
if (!instance) {
instance = init();
}
return instance;
};
return {
getInstance: getInstance
}
})();
var obj1 = singleton.getInstance();
var obj2 = singleton.getInstance();
console.log(obj1 === obj2); // Check for type and value.
我需要几个单人间:
延迟初始化 初始参数
这就是我想到的:
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。构造也是可能的。
推荐文章
- 在React Native中使用Fetch授权头
- 为什么我的球(物体)没有缩小/消失?
- 如何使用jQuery检测页面的滚动位置
- if(key in object)或者if(object. hasownproperty (key)
- 一元加/数字(x)和parseFloat(x)之间的区别是什么?
- angularjs中的compile函数和link函数有什么区别
- 删除绑定中添加的事件监听器
- 很好的初学者教程socket.io?
- HtmlSpecialChars在JavaScript中等价于什么?
- 如何向一个5岁的孩子解释依赖注入?
- 函数应该返回空对象还是空对象?
- React: 'Redirect'没有从' React -router-dom'中导出
- 如何在React中使用钩子强制组件重新渲染?
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?