JavaScript에서 싱글 톤 패턴을 구현하는 가장 간단하고 깨끗한 방법은 무엇입니까?
JavaScript에서 싱글 톤 패턴을 구현하는 가장 간단하고 깨끗한 방법은 무엇입니까?
답변:
가장 쉬운 방법은 간단한 객체 리터럴을 선언하는 것입니다.
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
싱글 톤 인스턴스에 비공개 멤버를 원하면 다음과 같이 할 수 있습니다.
var myInstance = (function() {
var privateVar = '';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accessible here
},
publicMethod2: function () {
}
};
})();
이를 모듈 패턴 이라고 하며 , 기본적으로 클로저를 사용하여 객체에 개인 멤버를 캡슐화 할 수 있습니다 .
업데이트 : 싱글 톤 객체의 수정을 방지 하려면 ES5 방법을 사용하여 고정 할 수 있다고 덧붙이고 싶습니다 Object.freeze
.
그러면 객체가 불변이되어 구조와 값이 수정되지 않습니다.
또한 ES6을 사용하는 경우 ES 모듈을 사용하여 싱글 톤을 매우 쉽게 나타낼 수 있으며 모듈 범위 에서 변수를 선언하여 개인 상태 를 유지할 수도 있습니다 .
// my-singleton.js
const somePrivateState = []
function privateFn () {
// ...
}
export default {
method1() {
// ...
},
method2() {
// ...
}
}
그런 다음 싱글 톤 객체를 가져 와서 사용할 수 있습니다.
import myInstance from './my-singleton.js'
// ...
publicMethod1
전화 publicMethod2
합니까?
getInstance
메소드와 개인 생성자를 포함한 많은 구현을 기억합니다 . 그러나 IMO는 싱글 톤 객체를 만드는 가장 "간단한"방법입니다. Javascript에서 마지막에는 동일한 목적을 달성합니다. 단일 객체는 다시 초기화 할 수 없습니다 (생성자가없고 객체 일뿐입니다). 링크 한 코드에 대해서는 몇 가지 문제가 a
있으며 b
변수 선언을 바꾸고 테스트하십시오 a === window
. 건배.
가장 깨끗한 접근 방식은 다음과 같습니다.
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();
delete instance.constructor
.x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
싱글 톤 패턴의 대체물로 사용되는 모듈 패턴에 동의하지 않습니다. 나는 종종 싱글 톤이 완전히 불필요한 곳에서 사용되고 남용되는 것을 보았으며, 프로그래머가 싱글 톤을 사용하는 모듈 패턴이 많은 간격을 메 우지 만 모듈 패턴은 싱글 톤 이 아닙니다 .
var foo = (function () {
"use strict";
function aPrivateFunction() {}
return { aPublicFunction: function () {...}, ... };
}());
모듈 패턴으로 초기화 된 모든 것은 Foo
선언 될 때 발생합니다 . 또한 모듈 패턴을 사용하여 생성자를 초기화 한 다음 여러 번 인스턴스화 할 수 있습니다. 모듈 패턴은 많은 작업에 적합한 도구이지만 싱글 톤과는 다릅니다.
var Foo = function () {
"use strict";
if (Foo._instance) {
//this allows the constructor to be called multiple times
//and refer to the same instance. Another option is to
//throw an error.
return Foo._instance;
}
Foo._instance = this;
//Foo initialization code
};
Foo.getInstance = function () {
"use strict";
return Foo._instance || new Foo();
}
모듈 패턴을 사용하는 긴 형식
var Foo = (function () {
"use strict";
var instance; //prevent modification of "instance" variable
function Singleton() {
if (instance) {
return instance;
}
instance = this;
//Singleton initialization code
}
//instance accessor
Singleton.getInstance = function () {
return instance || new Singleton();
}
return Singleton;
}());
내가 제공 한 Singleton 패턴의 두 버전 모두에서 생성자 자체를 접근 자로 사용할 수 있습니다.
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
또한 싱글 톤 패턴은 암시 적 생성자 함수 패턴과 잘 어울립니다.
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
var singleton = {}
그 정의에 맞지 않습니다.
var singleton = {}
Javascript에서 싱글 톤을 구현하는 방법 입니다.
에서 es6
:
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
instance
필드 만 있으면 얼리는 것이 합리적 입니다. 현재 (로 instance
설정 됨 this
)이 클래스에는 다른 필드도있을 수 있으며 동결은 의미가 없습니다.
다음은 노드 v6에서 작동합니다.
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' }
ES6에서이를 수행하는 올바른 방법은 다음과 같습니다.
class MyClass {
constructor() {
if (MyClass._instance) {
throw new Error("Singleton classes can't be instantiated more than once.")
}
MyClass._instance = this;
// ... your rest of the constructor code goes after this
}
}
var instanceOne = new MyClass() // Executes succesfully
var instanceTwo = new MyClass() // Throws error
또는 두 번째 인스턴스 생성시 오류가 발생하지 않게하려면 다음과 같이 마지막 인스턴스를 반환하면됩니다.
class MyClass {
constructor() {
if (MyClass._instance) {
return MyClass._instance
}
MyClass._instance = this;
// ... your rest of the constructor code goes after this
}
}
var instanceOne = new MyClass()
var instanceTwo = new MyClass()
console.log(instanceOne === instanceTwo) // logs "true"
instance
하고 _instance
. 밑줄이 앞에 붙은 개인 변수의 이름을 지정하는 것은 프로그래밍 언어의 명명 규칙입니다 . 코드가 작동하지 않는 이유는 귀하가 this.instance
대신 사용하고 있기 때문 입니다MyClass.instance
고양이를 피부에 바르는 방법은 여러 가지가 있습니다 :) 당신의 취향이나 특정한 필요에 따라 제안 된 솔루션을 적용 할 수 있습니다. 개인 정보가 필요하지 않은 경우 가능하면 CMS의 첫 번째 솔루션을 개인적으로 선택합니다. 질문이 가장 단순하고 깨끗하다는 것이 었으므로 이것이 승자입니다. 또는:
var myInstance = {}; // done!
이것은 (내 블로그에서 인용) ...
var SingletonClass = new function() {
this.myFunction() {
//do stuff
}
this.instance = 1;
}
개인 var가 필요 없기 때문에 이해가되지 않습니다 (블로그 예제도 마찬가지입니다). 그래서 다음과 거의 같습니다.
var SingletonClass = {
myFunction: function () {
//do stuff
},
instance: 1
}
this.f(){}
답변을 더 이상 사용하지 않습니다 . 다른 답변을 참조하십시오 .
일반적으로 싱글 톤 패턴이 아닌 모듈 패턴 (CMS의 답변 참조)으로 충분합니다. 그러나 싱글 톤의 기능 중 하나는 객체가 필요할 때까지 초기화가 지연된다는 것입니다. 모듈 패턴에는이 기능이 없습니다.
내 제안 (CoffeeScript) :
window.singleton = (initializer) ->
instance = undefined
() ->
return instance unless instance is undefined
instance = initializer()
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
JavaScript의 비 차단 특성으로 인해 JavaScript의 싱글 톤이 실제로 사용되지 않습니다. 전역 변수는 이러한 콜백없이 전체 애플리케이션을 통해 하나의 인스턴스를 제공하며 모듈 패턴은 인터페이스 뒤에 내부를 부드럽게 숨 깁니다. @CMS 답변을 참조하십시오.
하지만 싱글 톤을 원했기 때문에…
var singleton = function(initializer) {
var state = 'initial';
var instance;
var queue = [];
var instanceReady = function(createdInstance) {
state = 'ready';
instance = createdInstance;
while (callback = queue.shift()) {
callback(instance);
}
};
return function(callback) {
if (state === 'initial') {
state = 'waiting';
queue.push(callback);
initializer(instanceReady);
} else if (state === 'waiting') {
queue.push(callback);
} else {
callback(instance);
}
};
};
용법:
var singletonInitializer = function(instanceReady) {
var preparedObject = {property: 'value'};
// calling instanceReady notifies singleton that instance is ready to use
instanceReady(preparedObject);
}
var s = singleton(singletonInitializer);
// get instance and use it
s(function(instance) {
instance.doSomething();
});
싱글 톤은 전체 애플리케이션을 통해 하나 이상의 인스턴스를 제공합니다. 초기화는 처음 사용할 때까지 지연됩니다. 초기화가 비싼 객체를 다룰 때 이것은 정말 큰 일입니다. 비용이 많이 드는 것은 일반적으로 I / O를 의미하며 JavaScript의 I / O는 항상 콜백을 의미합니다.
와 같은 인터페이스를 제공하는 답변을 믿지 마십시오 instance = singleton.getInstance()
. 모두 요점을 놓칩니다.
인스턴스가 준비 될 때 콜백을 실행하지 않으면 초기화 프로그램이 I / O를 수행 할 때 작동하지 않습니다.
예, 콜백은 항상 객체 인스턴스를 즉시 반환하는 함수 호출보다 더 나빠 보입니다. 그러나 다시 : I / O를 수행 할 때 콜백은 필수입니다. I / O를 원하지 않는 경우 인스턴스화는 프로그램 시작시 수행하기에 충분히 저렴합니다.
var simpleInitializer = function(instanceReady) {
console.log("Initializer started");
instanceReady({property: "initial value"});
}
var simple = singleton(simpleInitializer);
console.log("Tests started. Singleton instance should not be initalized yet.");
simple(function(inst) {
console.log("Access 1");
console.log("Current property value: " + inst.property);
console.log("Let's reassign this property");
inst.property = "new value";
});
simple(function(inst) {
console.log("Access 2");
console.log("Current property value: " + inst.property);
});
이 예 setTimeout
에서는 값 비싼 I / O 작업을 위조합니다. 이것은 JavaScript의 싱글 톤에 실제로 콜백이 필요한 이유를 보여줍니다.
var heavyInitializer = function(instanceReady) {
console.log("Initializer started");
var onTimeout = function() {
console.log("Initializer did his heavy work");
instanceReady({property: "initial value"});
};
setTimeout(onTimeout, 500);
};
var heavy = singleton(heavyInitializer);
console.log("In this example we will be trying");
console.log("to access singleton twice before it finishes initialization.");
heavy(function(inst) {
console.log("Access 1");
console.log("Current property value: " + inst.property);
console.log("Let's reassign this property");
inst.property = "new value";
});
heavy(function(inst) {
console.log("Access 2. You can see callbacks order is preserved.");
console.log("Current property value: " + inst.property);
});
console.log("We made it to the end of the file. Instance is not ready yet.");
JavaScript 패턴 에서이 예제를 얻었습니다. 코딩 및 디자인 패턴으로 더 나은 응용 프로그램 빌드 Stoyan Stefanov 의 저서 singltone 객체와 같은 간단한 구현 클래스가 필요한 경우 다음과 같이 즉각적인 기능을 사용할 수 있습니다.
var ClassName;
(function() {
var instance;
ClassName = function ClassName() {
//If private instance variable already initialized return reference
if(instance) {
return instance;
}
//If instance does not created save pointer of original reference
//to private instance variable.
instance = this;
//All constructor initialization will be here
// i.e.:
this.someProperty = 0;
this.someMethod = function() {
//Some action here
};
};
}());
다음 테스트 사례를 통해이 예제를 확인할 수 있습니다.
//Extending defined class like Singltone object using new prototype property
ClassName.prototype.nothing = true;
var obj_1 = new ClassName();
//Extending defined class like Singltone object using new prototype property
ClassName.prototype.everything = true;
var obj_2 = new ClassName();
//Testing does this two object pointing to same instance
console.log(obj_1 === obj_2); //Result is true, it points to same instance object
//All prototype properites work
//no matter when they were defined
console.log(obj_1.nothing && obj_1.everything
&& obj_2.nothing && obj_2.everything); //Result true
//Values of properties which is defined inside of constructor
console.log(obj_1.someProperty);// output 0
console.log(obj_2.someProperty);// output 0
//Changing property value
obj_1.someProperty = 1;
console.log(obj_1.someProperty);// output 1
console.log(obj_2.someProperty);// output 1
console.log(obj_1.constructor === ClassName); //Output true
이 접근법은 프로토 타입 확장을 사용할 때 (고정 될 수는 있지만 간단하지는 않지만) 개인 정적 구현이 실패하고 인스턴스로 인해 공개 정적 구현이 권장되지 않는 경우 모든 테스트 사례를 통과합니다.
JavaScript로 프로그래밍하는 가장 깨끗한 방법을 찾았지만 상상력이 필요합니다. 이 아이디어는 "javascript the good parts"책의 작동 기술에서 얻었습니다.
새 키워드를 사용하는 대신 다음과 같은 클래스를 만들 수 있습니다.
function Class()
{
var obj = {}; // Could also be used for inheritence 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();
완전한 "클래스"에 액세스 할 수 없기 때문에 이것이 가장 쉬운 방법이라고 생각합니다.
@CMS와 @zzzzBov는 훌륭한 답변을 주었지만 싱글 톤 패턴이 일반적인 PHP / Zend Framework에서 무거운 node.js 개발로 옮겨 간 것에 근거하여 내 자신의 해석을 추가하기 만하면됩니다.
다음 주석으로 작성된 코드는 다음 요구 사항을 기반으로합니다.
내 코드는 @zzzzBov와 매우 유사합니다. 제작자에 프로토 타입 체인을 추가했으며 PHP 또는 유사한 언어에서 온 사람들이 전통적인 OOP를 Javascripts 프로토 타입으로 변환하는 데 도움이되는 더 많은 주석을 추가했습니다. "가장 단순하지"는 않지만 가장 적절하다고 생각합니다.
// declare 'Singleton' as the returned value of a self-executing anonymous function
var Singleton = (function () {
"use strict";
// 'instance' and 'constructor' should not be availble in a "public" scope
// here they are "private", thus available only within
// the scope of the self-executing anonymous function
var _instance=null;
var _constructor = function (name) {
this.name = name || 'default';
}
// prototypes will be "public" methods available from the instance
_constructor.prototype.getName = function () {
return this.name;
}
// using the module pattern, return a static object
// which essentially is a list of "public static" methods
return {
// because getInstance is defined within the same scope
// it can access the "private" 'instance' and 'constructor' vars
getInstance:function (name) {
if (!_instance) {
console.log('creating'); // this should only happen once
_instance = new _constructor(name);
}
console.log('returning');
return _instance;
}
}
})(); // self execute
// ensure 'instance' and 'constructor' are unavailable
// outside the scope in which they were defined
// thus making them "private" and not "public"
console.log(typeof _instance); // undefined
console.log(typeof _constructor); // undefined
// assign instance to two different variables
var a = Singleton.getInstance('first');
var b = Singleton.getInstance('second'); // passing a name here does nothing because the single instance was already instantiated
// ensure 'a' and 'b' are truly equal
console.log(a === b); // true
console.log(a.getName()); // "first"
console.log(b.getName()); // also returns "first" because it's the same instance as 'a'
기술적으로, 자체 실행 익명 함수는 @CMS에서 제공 한 코드에서 잘 설명 된대로 자체적으로 싱글 톤입니다. 여기서 유일한 발견은 생성자 자체가 익명 인 경우 생성자의 프로토 타입 체인을 수정할 수 없다는 것입니다.
Javascript의 경우 "public"및 "private"개념은 PHP 또는 Java에서와 같이 적용되지 않습니다. 그러나 Javascript의 기능 범위 가용성 규칙을 활용하여 동일한 효과를 얻었습니다.
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
가장 분명한 답은 Addy Osmani의 Learning JavaScript Design Patterns 책에서 나온 것입니다.
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 = "Im 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;
}
};
})();
ES7이 필요하지만 가장 단순하고 깨끗하고 직관적 인 방법이라고 생각합니다.
export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } }
소스 코드는 다음과 같습니다 : adam-bien.com
new Singleton()
다음은 자바 스크립트에서 싱글 톤 패턴을 설명하는 간단한 예입니다.
var Singleton=(function(){
var instance;
var init=function(){
return {
display:function(){
alert("This is a Singleton patern 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 patern demo");
// It means one object is created
var inst=Singleton.getInstance();
inst.display();
// In this call only display alert("This is a Singleton patern demo")
// it means second time new object is not created,
// it uses the already created object
var inst1=Singleton.getInstance();
inst1.display();
나는 몇 가지 싱글 톤이 필요했습니다.
그래서 이것은 내가 생각해 낸 것입니다.
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;
}
빈 변수가 있으면 [] 만 전달하면됩니다.
함수에서 창 객체를 사용했지만 매개 변수를 전달하여 자체 범위를 만들 수있었습니다.
name 및 construct 매개 변수는 window []가 작동하기위한 문자열 일 뿐이며 간단한 유형 검사를 통해 window.name 및 window.construct도 가능합니다.
이런 식으로 수업을 다시 시작할 수 없도록하십시오.
이를 통해 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');}
}
// initilize the instance
new CA();
// test here
var c = CA.getInstance()
c.func();
console.assert(c instanceof CA)
// this will failed
var b = new CA();
instance
멤버 를 노출시키지 않으려면 멤버를 클로저에 넣으십시오.
다음은 싱글 톤 패턴을 구현하기 위해 걷는 스 니펫입니다. 이것은 인터뷰 과정에서 나에게 일어 났고 나는 이것을 어딘가에 포착해야한다고 느꼈다.
/*************************************************
* SINGLETON PATTERN IMPLEMENTATION *
*************************************************/
//since there are no classes in javascript, every object is technically a singleton
//if you don't inherit from it or copy from it.
var single = {};
//Singleton Implementations
//Declaring as a Global Object...you are being judged!
var Logger = function() {
//global_log is/will be defined in GLOBAL scope here
if(typeof global_log === 'undefined'){
global_log = this;
}
return global_log;
};
//the below 'fix' solves the GLOABL variable problem but
//the log_instance is publicly available and thus can be
//tampered with.
function Logger() {
if(typeof Logger.log_instance === 'undefined'){
Logger.log_instance = this;
}
return Logger.log_instance;
};
//the correct way to do it to give it a closure!
function logFactory() {
var log_instance; //private instance
var _initLog = function() { //private init method
log_instance = 'initialized';
console.log("logger initialized!")
}
return {
getLog : function(){ //the 'privileged' method
if(typeof log_instance === 'undefined'){
_initLog();
}
return log_instance;
}
};
}
/***** TEST CODE ************************************************
//using the Logger singleton
var logger = logFactory();//did i just gave LogFactory a closure?
//create an instance of the logger
var a = logger.getLog();
//do some work
//get another instance of the logger
var b = logger.getLog();
//check if the two logger instances are same?
console.log(a === b); //true
*******************************************************************/
내 요지 페이지 에서도 마찬가지입니다 .
function Unicode()
{
var i = 0, unicode = {}, zero_padding = "0000", max = 9999;
//Loop through code points
while (i < max) {
//Convert decimal to hex value, find the character, then pad zeroes to the codepoint
unicode[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);
i = i + 1;
}
//Replace this function with the resulting lookup table
Unicode = unicode;
}
//Usage
Unicode();
//Lookup
Unicode["%"]; //returns 0025
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와 같은 컴파일러를 사용해야합니다.
또한 싱글 톤 인스턴스는 "lazy"로 작성됩니다. 즉, 처음 사용할 때만 작성됩니다.
모듈 패턴 : "더 읽기 쉬운 스타일" 어떤 방법이 공개인지, 어떤 방법이 비공개인지 쉽게 볼 수 있습니다
var module = (function(_name){
/*Local Methods & Values*/
var _local = {
name : _name,
flags : {
init : false
}
}
function init(){
_local.flags.init = true;
}
function imaprivatemethod(){
alert("hi im a private method");
}
/*Public Methods & variables*/
var $r = {}; //this object will hold all public methods.
$r.methdo1 = function(){
console.log("method1 call 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 init method
return $r; //returning all publics methods
})("module");
지금 당신은 같은 공개 방법을 사용할 수 있습니다
module.method2 (); //-> 공개 메소드 알림 ( "hi im a private method")을 통해 비공개 메소드를 호출하고 있습니다.
하나씩 일어나는 것:
클래스에 인스턴스가 하나만 있는지 확인하고 글로벌 액세스 지점을 제공하십시오.
싱글 톤 패턴은 특정 객체의 인스턴스 수를 하나로 제한합니다. 이 단일 인스턴스를 싱글 톤이라고합니다.
Singleton 객체는 즉각적인 익명 함수로 구현됩니다. 이 함수는 대괄호로 묶은 다음 두 개의 추가 대괄호로 즉시 실행됩니다. 이름이 없기 때문에 익명이라고합니다.
샘플 프로그램,
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
function run() {
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
alert("Same instance? " + (instance1 === instance2));
}
run()
나를 위해 가장 단순하고 깨끗하다는 것은 Java 버전의 토론에서 많이 논의 된 것처럼 단순히 이해하고 종소리와 휘파람을 의미하지 않는다는 것을 의미합니다.
Java에서 싱글 톤 패턴을 구현하는 효율적인 방법은 무엇입니까?
내 관점에서 가장 간단하고 깨끗하게 맞는 대답은 다음과 같습니다.
https://stackoverflow.com/a/70824/1497139
그리고 그것은 부분적으로 JavaScript로 번역 될 수 있습니다. Javascript의 차이점 중 일부는 다음과 같습니다.
그러나 최신 ECMA 구문이 제공되면 다음과 같이 접근 할 수 있습니다.
JavaScript 클래스 예제로서의 싱글 톤 패턴
class Singleton {
constructor(field1,field2) {
this.field1=field1;
this.field2=field2;
Singleton.instance=this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance=new Singleton('DefaultField1','DefaultField2');
}
return Singleton.instance;
}
}
사용법 예
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
클래스를 사용하려는 경우 :
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