जावास्क्रिप्ट में सिंगलटन पैटर्न को लागू करने का सबसे सरल / साफ तरीका क्या है?
जावास्क्रिप्ट में सिंगलटन पैटर्न को लागू करने का सबसे सरल / साफ तरीका क्या है?
जवाबों:
मुझे लगता है कि सबसे आसान तरीका एक साधारण वस्तु घोषित करना है:
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 () {
}
};
})();
इसे मॉड्यूल पैटर्न कहा गया है , यह मूल रूप से आपको किसी वस्तु पर निजी सदस्यों को बंद करने के लाभ का लाभ उठाने की अनुमति देता है ।
अद्यतन: मैं जोड़ना चाहूंगा कि यदि आप सिंगलटन ऑब्जेक्ट के संशोधन को रोकना चाहते हैं, तो आप इसे ईएस 5 का उपयोग करके फ्रीज कर सकते हैं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, यह एक सिंगलटन ऑब्जेक्ट बनाने का सबसे "सरल" तरीका है जावास्क्रिप्ट में, और अंत में यह एक ही उद्देश्य-एक एकल वस्तु से मिलता है, कि आप फिर से इनिशियलाइज़ नहीं कर सकते (कोई कंस्ट्रक्टर नहीं है, यह सिर्फ एक ऑब्जेक्ट है) -। आपके द्वारा लिंक किए गए कोड के बारे में, इसमें कुछ समस्याएं हैं, स्वैप 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;
}());
मेरे द्वारा प्रदान किए गए सिंगलटन पैटर्न के दोनों संस्करणों में, कंस्ट्रक्टर को ही एक्सेसर के रूप में इस्तेमाल किया जा सकता है:
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 = {}
आप जावास्क्रिप्ट में सिंगलटन को कैसे लागू करते हैं ।
इन 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
एक बिल्ली की त्वचा के लिए एक से अधिक तरीके हैं :) अपने स्वाद या विशिष्ट आवश्यकता के आधार पर आप किसी भी प्रस्तावित समाधान को लागू कर सकते हैं। जब भी संभव हो (जब आपको गोपनीयता की आवश्यकता नहीं हो) मैं व्यक्तिगत रूप से सीएमएस के पहले समाधान के लिए जाता हूं। चूंकि सवाल सबसे सरल और साफ-सुथरा था, इसलिए वह विजेता है। या और भी:
var myInstance = {}; // done!
यह (मेरे ब्लॉग से उद्धरण) ...
var SingletonClass = new function() {
this.myFunction() {
//do stuff
}
this.instance = 1;
}
ज्यादा मतलब नहीं है (मेरे ब्लॉग का उदाहरण या तो नहीं है) क्योंकि इसे किसी भी निजी संस्करण की आवश्यकता नहीं है, इसलिए यह बहुत समान है:
var SingletonClass = {
myFunction: function () {
//do stuff
},
instance: 1
}
this.f(){}
मैं अपने जवाब को चित्रित करता हूं, मेरे दूसरे को देखें ।
आमतौर पर मॉड्यूल पैटर्न (सीएमएस का उत्तर देखें) जो सिंगलटन पैटर्न नहीं है, काफी अच्छा है। हालाँकि सिंगलटन की एक विशेषता यह है कि इसके आरंभीकरण में देरी तब तक की जाती है जब तक कि वस्तु की आवश्यकता नहीं होती। मॉड्यूल पैटर्न में इस सुविधा का अभाव है।
मेरा प्रस्ताव (कॉफीस्क्रिप्ट):
window.singleton = (initializer) ->
instance = undefined
() ->
return instance unless instance is undefined
instance = initializer()
इसे जावास्क्रिप्ट में संकलित किया गया है:
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
क्योंकि जावास्क्रिप्ट की गैर-अवरुद्ध प्रकृति, जावास्क्रिप्ट में सिंग्लेटन्स वास्तव में उपयोग में बदसूरत हैं। वैश्विक चर आपको इन सभी कॉलबैक के बिना भी पूरे एप्लिकेशन के माध्यम से एक उदाहरण देगा, मॉड्यूल पैटर्न धीरे-धीरे इंटरफ़ेस के पीछे आंतरिक छुपाता है। देखिए @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 होता है और जावास्क्रिप्ट 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 ऑपरेशन किए गए हैं। यह दिखाता है कि जावास्क्रिप्ट में सिंगलटन को वास्तव में कॉलबैक की आवश्यकता क्यों है।
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.");
मुझे यह उदाहरण दिया गया है कि स्टोअन स्टेफानोव की पुस्तक के पैटर्न और कोडिंग के साथ बेहतर पैटर्न बनाएँ
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
यह दृष्टिकोण सभी परीक्षण मामलों को पास करता है जबकि निजी स्थैतिक कार्यान्वयन विफल हो जाएगा जब प्रोटोटाइप एक्सटेंशन का उपयोग किया जाता है (इसे ठीक किया जा सकता है लेकिन यह सरल नहीं होगा) और सार्वजनिक स्थैतिक कार्यान्वयन कम सलाह दी जाती है, उदाहरण के लिए जनता के संपर्क में है।
मुझे लगता है कि मुझे जावास्क्रिप्ट में प्रोग्राम करने का सबसे साफ तरीका मिल गया है, लेकिन आपको कुछ कल्पना की आवश्यकता होगी। मुझे यह विचार "अच्छे भागों की जावास्क्रिप्ट" पुस्तक में एक कामकाजी तकनीक से मिला।
नए कीवर्ड का उपयोग करने के बजाय, आप इस तरह एक वर्ग बना सकते हैं:
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 फ्रेमवर्क से विकास जहां सिंगलटन पैटर्न सामान्य थे।
निम्नलिखित, टिप्पणी-दस्तावेज कोड निम्नलिखित आवश्यकताओं पर आधारित है:
मेरा कोड @ 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 द्वारा प्रदान किए गए कोड में अच्छी तरह से प्रदर्शित किया गया है। यहां एकमात्र पकड़ यह है कि कंस्ट्रक्टर की प्रोटोटाइप श्रृंखला को संशोधित करना संभव नहीं है, जब कंस्ट्रक्टर खुद गुमनाम हो।
यह ध्यान रखें कि जावास्क्रिप्ट के लिए, "सार्वजनिक" और "निजी" की अवधारणाएं लागू नहीं होती हैं जैसा कि वे PHP या जावा में करते हैं। लेकिन हमने जावास्क्रिप्ट के कार्यात्मक गुंजाइश उपलब्धता के नियमों का लाभ उठाकर एक ही प्रभाव प्राप्त किया है।
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
यकीन नहीं होता कि कोई भी इसे क्यों नहीं लाया है, लेकिन आप ऐसा कर सकते हैं:
var singleton = new (function() {
var bar = 123
this.foo = function() {
// whatever
}
})()
सबसे स्पष्ट उत्तर यह है कि Addy Osmani द्वारा लर्निंग जावास्क्रिप्ट डिज़ाइन पैटर्न की पुस्तक से यह एक होना चाहिए।
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()
क्या मैं अपने 5 सिक्के डाल सकता हूँ? मेरे पास एक निर्माण कार्य है, पूर्व।
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)
मैंने निम्नलिखित को सबसे आसान सिंगलटन पैटर्न पाया है, क्योंकि नए ऑपरेटर का उपयोग करने से यह फंक्शन के भीतर तुरंत उपलब्ध हो जाता है, जिससे एक वस्तु शाब्दिक वापसी की आवश्यकता समाप्त हो जाती है:
var singleton = new (function () {
var private = "A private value";
this.printSomething = function() {
console.log(private);
}
})();
singleton.printSomething();
यहाँ जावास्क्रिप्ट में सिंगलटन पैटर्न को समझाने का सरल उदाहरण है।
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;
}
यह काम करने के लिए आर्गेज होना चाहिए, यदि आपके पास खाली चर हैं, तो [
मैंने फ़ंक्शन में विंडो ऑब्जेक्ट का उपयोग किया था लेकिन मैं अपना स्वयं का दायरा बनाने के लिए एक पैरामीटर में पारित कर सकता था
नाम और निर्माण पैरामीटर केवल काम करने के लिए खिड़की [] के लिए स्ट्रिंग हैं लेकिन कुछ सरल प्रकार की जाँच के साथ, window.name और window.construct भी संभव है।
इस तरह से कैसे, बस बीमा फिर से नया नहीं हो सकता है।
इसके द्वारा, आप instanceof
सेशन का उपयोग कर सकते हैं , साथ ही, आप क्लास को इनहेरिट करने के लिए प्रोटोटाइप चेन का उपयोग कर सकते हैं, यह एक रेगुलर क्लास है, लेकिन इसे नया नहीं कर सकते हैं, यदि यूयू सिर्फ उदाहरण का उपयोग करना चाहते हैं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
आप इसे इस प्रकार से डेकोरेटर के साथ कर सकते हैं, उदाहरण के लिए टाइपस्क्रिप्ट के लिए नीचे:
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();
इस लेखन के रूप में, डेकोरेटर जावास्क्रिप्ट इंजन में आसानी से उपलब्ध नहीं हैं। आपको यह सुनिश्चित करने की आवश्यकता होगी कि आपके जावास्क्रिप्ट रनटाइम में सज्जाकार वास्तव में सक्षम हैं या बैबिल और टाइपस्क्रिप्ट जैसे संकलक का उपयोग करते हैं।
यह भी ध्यान दें कि सिंगलटन उदाहरण "आलसी" बनाया गया है, अर्थात, यह केवल तभी बनाया जाता है जब आप इसे पहली बार उपयोग करते हैं।
मॉड्यूल पैटर्न: "अधिक पठनीय शैली" में। आप आसानी से देख सकते हैं कि कौन से तरीके सार्वजनिक हैं और कौन से निजी हैं
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 (); // -> मैं एक सार्वजनिक विधि चेतावनी ("हाय im एक निजी विधि") पर एक निजी विधि कह रहा हूँ
सिंगलटन:
सुनिश्चित करें कि एक वर्ग के पास केवल एक ही उदाहरण है और उसे वैश्विक पहुँच प्रदान करना है।
सिंगलटन पैटर्न किसी विशेष वस्तु के उदाहरणों की संख्या को केवल एक तक सीमित करता है। इस एकल उदाहरण को सिंगलटन कहा जाता है।
सिंगलटन ऑब्जेक्ट को तत्काल अनाम फ़ंक्शन के रूप में कार्यान्वित किया जाता है। फ़ंक्शन तुरंत ब्रैकेट में लपेटकर निष्पादित करता है, इसके बाद दो अतिरिक्त कोष्ठक होते हैं। इसे अनाम कहा जाता है क्योंकि इसका कोई नाम नहीं है।
नमूना कार्यक्रम,
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()
मेरे लिए सबसे सरल / साफ-सुथरा मतलब यह है कि केवल समझने के लिए कोई घंटी और सीटी नहीं है क्योंकि चर्चा के जावा संस्करण में बहुत चर्चा की जाती है:
जावा में सिंगलटन पैटर्न को लागू करने का एक प्रभावी तरीका क्या है?
जो उत्तर मेरे दृष्टिकोण से सबसे सरल / सबसे अच्छा होगा, वह है:
https://stackoverflow.com/a/70824/1497139
और इसे केवल आंशिक रूप से जावास्क्रिप्ट में अनुवादित किया जा सकता है। जावास्क्रिप्ट में कुछ अंतर हैं:
लेकिन नवीनतम ECMA सिंटैक्स दिए जाने से यह संभव है:
जावास्क्रिप्ट क्लास उदाहरण के रूप में सिंगलटन पैटर्न
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