在JavaScript中实现单例的最简单/最干净的方法
在JavaScript中实现的最简单/最干净的方法是什么?我认为最简单的方法是声明一个简单的对象文字:在JavaScript中实现单例的最简单/最干净的方法,javascript,function,design-patterns,singleton,Javascript,Function,Design Patterns,Singleton,在JavaScript中实现的最简单/最干净的方法是什么?我认为最简单的方法是声明一个简单的对象文字: var myInstance = { method1: function () { // ... }, method2: function () { // ... } }; 如果您想在singleton实例上使用私有成员,可以执行以下操作: var myInstance = (function() { var privateVar = ''; fun
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
如果您想在singleton实例上使用私有成员,可以执行以下操作:
var myInstance = (function() {
var privateVar = '';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// All private members are accessible here
},
publicMethod2: function () {
}
};
})();
function Class()
{
var obj = {}; // Could also be used for inheritance if you don't start with an empty object.
var privateVar;
obj.publicVar;
obj.publicMethod = publicMethod;
function publicMethod(){}
function privateMethod(){}
return obj;
}
ClassSingleton = function()
{
var instance = null;
function Class() // This is the class like the above one
{
var obj = {};
return obj;
}
function getInstance()
{
if( !instance )
instance = Class(); // Again no 'new' keyword;
return instance;
}
return { getInstance : getInstance };
}();
var myInstance = YourClass.singleton();
这被称为,它基本上允许您通过使用来封装对象上的私有成员
如果要防止修改singleton对象,可以使用ES5方法冻结它
这将使对象不可变,防止对其结构和值进行任何修改
如果您使用的是ES6,那么您可以非常轻松地使用ES模块来表示一个单例,甚至可以通过在模块范围内声明变量来保持私有状态:
然后,只需导入singleton对象即可使用它:
import myInstance from './my-singleton.js'
// ...
我认为最简单的方法是声明一个简单的对象文字:
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
如果您想在singleton实例上使用私有成员,可以执行以下操作:
var myInstance = (function() {
var privateVar = '';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// All private members are accessible here
},
publicMethod2: function () {
}
};
})();
function Class()
{
var obj = {}; // Could also be used for inheritance if you don't start with an empty object.
var privateVar;
obj.publicVar;
obj.publicMethod = publicMethod;
function publicMethod(){}
function privateMethod(){}
return obj;
}
ClassSingleton = function()
{
var instance = null;
function Class() // This is the class like the above one
{
var obj = {};
return obj;
}
function getInstance()
{
if( !instance )
instance = Class(); // Again no 'new' keyword;
return instance;
}
return { getInstance : getInstance };
}();
var myInstance = YourClass.singleton();
这被称为,它基本上允许您通过使用来封装对象上的私有成员
如果要防止修改singleton对象,可以使用ES5方法冻结它
这将使对象不可变,防止对其结构和值进行任何修改
如果您使用的是ES6,那么您可以非常轻松地使用ES模块来表示一个单例,甚至可以通过在模块范围内声明变量来保持私有状态:
然后,只需导入singleton对象即可使用它:
import myInstance from './my-singleton.js'
// ...
我认为最干净的方法是:
var SingletonFactory = (function(){
function SingletonClass() {
//do stuff
}
var instance;
return {
getInstance: function(){
if (instance == null) {
instance = new SingletonClass();
// Hide the constructor so the returned object can't be new'd...
instance.constructor = null;
}
return instance;
}
};
})();
之后,您可以根据需要调用该函数
var test = SingletonFactory.getInstance();
我认为最干净的方法是:
var SingletonFactory = (function(){
function SingletonClass() {
//do stuff
}
var instance;
return {
getInstance: function(){
if (instance == null) {
instance = new SingletonClass();
// Hide the constructor so the returned object can't be new'd...
instance.constructor = null;
}
return instance;
}
};
})();
之后,您可以根据需要调用该函数
var test = SingletonFactory.getInstance();
给猫剥皮的方法不止一种:)根据你的口味或具体需要,你可以采用任何建议的解决方案。只要有可能(当你不需要隐私时),我个人都会选择 既然问题是关于最简单和最干净的,那就是赢家。甚至:
var myInstance = {}; // Done!
这(引用我的博客)
没有多大意义(我的博客示例也没有),因为它不需要任何私有变量,所以它与:
var SingletonClass = {
myFunction: function () {
// Do stuff
},
instance: 1
}
给猫剥皮的方法不止一种:)根据你的口味或具体需要,你可以采用任何建议的解决方案。只要有可能(当你不需要隐私时),我个人都会选择 既然问题是关于最简单和最干净的,那就是赢家。甚至:
var myInstance = {}; // Done!
这(引用我的博客)
没有多大意义(我的博客示例也没有),因为它不需要任何私有变量,所以它与:
var SingletonClass = {
myFunction: function () {
// Do stuff
},
instance: 1
}
我不赞成我的回答,明白吗 通常模块模式(请参阅)不是单例模式就足够了。但是,singleton的一个特性是它的初始化延迟到需要对象时。模块模式缺少此功能 我的建议(咖啡脚本): 在JavaScript中编译为:
window.singleton = function(initializer) {
var instance;
instance = void 0;
return function() {
if (instance !== void 0) {
return instance;
}
return instance = initializer();
};
};
然后我可以做以下几点:
window.iAmSingleton = singleton(function() {
/* This function should create and initialize singleton. */
alert("creating");
return {property1: 'value1', property2: 'value2'};
});
alert(window.iAmSingleton().property2); // "creating" will pop up; then "value2" will pop up
alert(window.iAmSingleton().property2); // "value2" will pop up but "creating" will not
window.iAmSingleton().property2 = 'new value';
alert(window.iAmSingleton().property2); // "new value" will pop up
var ClassName;
(function() {
var instance;
ClassName = function ClassName() {
// If the private instance variable is already initialized, return a reference
if(instance) {
return instance;
}
// If the instance is not created, save a pointer of the original reference
// to the private instance variable.
instance = this;
// All constructor initialization will be here
// i.e.:
this.someProperty = 0;
this.someMethod = function() {
// Some action here
};
};
}());
我不赞成我的回答,明白吗 通常模块模式(请参阅)不是单例模式就足够了。但是,singleton的一个特性是它的初始化延迟到需要对象时。模块模式缺少此功能 我的建议(咖啡脚本): 在JavaScript中编译为:
window.singleton = function(initializer) {
var instance;
instance = void 0;
return function() {
if (instance !== void 0) {
return instance;
}
return instance = initializer();
};
};
然后我可以做以下几点:
window.iAmSingleton = singleton(function() {
/* This function should create and initialize singleton. */
alert("creating");
return {property1: 'value1', property2: 'value2'};
});
alert(window.iAmSingleton().property2); // "creating" will pop up; then "value2" will pop up
alert(window.iAmSingleton().property2); // "value2" will pop up but "creating" will not
window.iAmSingleton().property2 = 'new value';
alert(window.iAmSingleton().property2); // "new value" will pop up
var ClassName;
(function() {
var instance;
ClassName = function ClassName() {
// If the private instance variable is already initialized, return a reference
if(instance) {
return instance;
}
// If the instance is not created, save a pointer of the original reference
// to the private instance variable.
instance = this;
// All constructor initialization will be here
// i.e.:
this.someProperty = 0;
this.someMethod = function() {
// Some action here
};
};
}());
我不确定我是否同意将模块模式用作单例模式的替代品。我经常看到在完全不必要的地方使用和滥用单例,我确信模块模式填补了程序员使用单例的许多空白。但是,模块模式不是单例模式 模块模式: 当声明
Foo
时,模块模式中初始化的所有内容都会发生。此外,模块模式可用于初始化构造函数,然后可以多次实例化构造函数。虽然模块模式是许多作业的正确工具,但它并不等同于单例
单件模式:
缩略形式
长格式,使用模块模式
在我提供的两个单例模式版本中,构造函数本身都可以用作访问器:
var a,
b;
a = new Foo(); // Constructor initialization happens here
b = new Foo();
console.log(a === b); //true
如果您不喜欢以这种方式使用构造函数,可以在If(instance)
语句中抛出一个错误,并坚持使用长格式:
var a,
b;
a = Foo.getInstance(); // Constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); // true
我还应该提到,singleton模式与隐式构造函数模式非常匹配:
function Foo() {
if (Foo._instance) {
return Foo._instance;
}
// If the function wasn't called as a constructor,
// call it as a constructor and return the result
if (!(this instanceof Foo)) {
return new Foo();
}
Foo._instance = this;
}
var f = new Foo(); // Calls Foo as a constructor
-or-
var f = Foo(); // Also calls Foo as a constructor
我不确定我是否同意将模块模式用作单例模式的替代品。我经常看到在完全不必要的地方使用和滥用单例,我确信模块模式填补了程序员使用单例的许多空白。但是,模块模式不是单例模式 模块模式: 当声明
Foo
时,模块模式中初始化的所有内容都会发生。此外,模块模式可用于初始化构造函数,然后可以多次实例化构造函数。虽然模块模式是许多作业的正确工具,但它并不等同于单例
单件模式:
缩略形式
长格式,使用模块模式
在我提供的两个单例模式版本中,构造函数本身都可以用作访问器:
var a,
b;
a = new Foo(); // Constructor initialization happens here
b = new Foo();
console.log(a === b); //true
如果您不喜欢以这种方式使用构造函数,可以在If(instance)
语句中抛出一个错误,并坚持使用长格式:
var a,
b;
a = Foo.getInstance(); // Constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); // true
我还应该提到,singleton模式与隐式构造函数模式非常匹配:
function Foo() {
if (Foo._instance) {
return Foo._instance;
}
// If the function wasn't called as a constructor,
// call it as a constructor and return the result
if (!(this instanceof Foo)) {
return new Foo();
}
Foo._instance = this;
}
var f = new Foo(); // Calls Foo as a constructor
-or-
var f = Foo(); // Also calls Foo as a constructor
我需要几个单身汉:
- 惰性初始化<
function Class() { var obj = {}; // Could also be used for inheritance if you don't start with an empty object. var privateVar; obj.publicVar; obj.publicMethod = publicMethod; function publicMethod(){} function privateMethod(){} return obj; }
var objInst = Class(); // !!! NO NEW KEYWORD
ClassSingleton = function() { var instance = null; function Class() // This is the class like the above one { var obj = {}; return obj; } function getInstance() { if( !instance ) instance = Class(); // Again no 'new' keyword; return instance; } return { getInstance : getInstance }; }();
var obj = ClassSingleton.getInstance();
function Singleton() { var i = 0; var self = this; this.doStuff = function () { i = i + 1; console.log('do stuff', i); }; Singleton = function () { return self }; return this; } s = Singleton(); s.doStuff();
var A = function(arg1){ this.arg1 = arg1 };
var X = function(){ var instance = {}; return function(){ return instance; } }();
var x1 = new X(); var x2 = new X(); console.log(x1 === x2)
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();
export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } }
class Singleton { constructor () { if (!Singleton.instance) { Singleton.instance = this } // Initialize object return Singleton.instance } // Properties & Methods } const instance = new Singleton() Object.freeze(instance) export default instance
var Singleton = (function() { var instance; var init = function() { return { display:function() { alert("This is a singleton pattern demo"); } }; }; return { getInstance:function(){ if(!instance){ alert("Singleton check"); instance = init(); } return instance; } }; })(); // In this call first display alert("Singleton check") // and then alert("This is a singleton pattern demo"); // It means one object is created var inst = Singleton.getInstance(); inst.display(); // In this call only display alert("This is a singleton pattern demo") // it means second time new object is not created, // it uses the already created object var inst1 = Singleton.getInstance(); inst1.display();
class Foo { constructor(msg) { if (Foo.singleton) { return Foo.singleton; } this.msg = msg; Foo.singleton = this; return Foo.singleton; } }
const f = new Foo('blah'); const d = new Foo('nope'); console.log(f); // => Foo { msg: 'blah' } console.log(d); // => Foo { msg: 'blah' }
console.log(Singleton.getInstance().field1); console.log(Singleton.getInstance().field2);
DefaultField1 DefaultField2
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
const singleton = new class { name = "foo" constructor() { console.log(`Singleton ${this.name} constructed`) } }
class Singleton { constructor(name, age) { this.name = name; this.age = age; if(this.constructor.instance) return this.constructor.instance; this.constructor.instance = this; } } let x = new Singleton('s', 1); let y = new Singleton('k', 2);
console.log(x.name, x.age, y.name, y.age) // s 1 s 1
function AnotherSingleton (name,age) { this.name = name; this.age = age; if(this.constructor.instance) return this.constructor.instance; this.constructor.instance = this; } let a = new AnotherSingleton('s', 1); let b = new AnotherSingleton('k', 2);
console.log(a.name, a.age, b.name, b.age) // s 1 s 1