Javascript-də təklüyü həyata keçirmək üçün ən sadə / təmiz yol?

Javascript-da bir tək nümunə tətbiq etmək üçün ən asan / təmiz üsul nədir?

262
25 сент. Jakub Arnold tərəfindən 25 Sentyabrda təyin olundu . 2009-09-25 23:05 '09 at 11:05 pm 2009-09-25 23:05
ответ 31 cavab
  • 1
  • 2

Mən ən asan yol sadə bir obyektin bəyan edilməsi olduğunu düşünürəm:

 var myInstance = { method1: function () { // ... }, method2: function () { // ... } }; 

Bir tək-tək namizədinizdə özəl üzvləriniz olmasını istəyirsinizsə, belə bir şey edə bilərsiniz:

 var myInstance = (function() { var privateVar = ''; function privateMethod () { // ... } return { // public interface publicMethod1: function () { // all private members are accesible here }, publicMethod2: function () { } }; })(); 

Buna modul bir şablon deyilir, əsasən bağlanmaların üstünlüklərini istifadə edərək, bir obyektdə qapalı elementləri əhatə etməyə imkan verir.

288
25 сент. cavab CMS 25 sep verilir . 2009-09-25 23:10 '09 at 11:10 pm 2009-09-25 23:10

Düşünürəm ki, ən təmiz yanaşma bir şeydir:

 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; } }; })(); 
border=0

Bundan sonra funksiyanı zəng edə bilərsiniz

 var test = SingletonFactory.getInstance(); 
153
30 янв. cavab verildi sebarmeli Jan 30 2011-01-30 15:50 '11 at 15:50 2011-01-30 15:50

Modul şablonunun bir element şablonunun əvəzi olaraq istifadə edildiyini qəbul etmədiyinə əmin deyiləm. Tez-tez gördüyüm ki, singletons tamamilə lazımsız yerlərdə istifadə olunur və istismar olunur, amma əminəm ki, proqram şablonu başqa elementləri istifadə edərkən modul şablonun bir çox boşluqları doldurur, amma modul şablonu tək deyil.

modul şablonu:

 var foo = (function () { "use strict"; function aPrivateFunction() {} return { aPublicFunction: function () {...}, ... }; }()); 

Bütün başlanğıc modul şablonları Foo elan edildikdə baş verir. Bundan əlavə, modul şablonu bir neçə dəfə yarana biləcək qurucuyu işə salmaq üçün istifadə edilə bilər. Modul şablonu çox tapşırıqlar üçün doğru vasitədirsə də, bir təklinə bərabər deyil.

tək nümunə nümunəsi:

qısa forma
 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(); } 
şablon modulunu istifadə edərək uzun formada
 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; }()); 

Sağladığım Singleton şablonunun hər iki versiyasında, konstruktor özü kimi istifadə edilə bilər:

 var a, b; a = new Foo(); //constructor initialization happens here b = new Foo(); console.log(a === b); //true 

Əgər bu şəkildə konstruktordan istifadə etməsəniz, if (instance) bir səhv çıxara və uzun formanı saxlaya bilərsiniz:

 var a, b; a = Foo.getInstance(); //constructor initialization happens here b = Foo.getInstance(); console.log(a === b); //true 

Həmçinin qeyd etmək lazımdır ki, tək nümunə örtük konstruktor funksiyası ilə yaxşı birləşir:

 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 
92
12 апр. cavab zzzzBov 12 apr verilir . 2012-04-12 20:08 '12 at 8:08 pm 2012-04-12 20:08

Bir neçə yolla pişik pişiklər var :) Zövqünüzə və ya xüsusi ehtiyaclarınıza bağlı olaraq, təklif olunan hər hansı bir həll yolunu tətbiq edə bilərsiniz. Mümkün olduğunda şəxsən ilk CMS həllinə gəlirəm (gizlilikə ehtiyac olmadıqda). Sual ən sadə və təmiz olduğundan, qalib oldu. Və ya hətta:

 var myInstance = {}; // done! 

Bu (mənim blog mənim quote) ...

 var SingletonClass = new function() { this.myFunction() { //do stuff } this.instance = 1; } 

hər hansı bir fərdi əşyaya ehtiyac olmadığı üçün çox mənalı deyil (mənim blog da uyğun deyil), belə ki, demək olar ki, eynidır:

 var SingletonClass = { myFunction: function () { //do stuff }, instance: 1 } 
8
28 июня '11 в 4:04 2011-06-28 04:04 Cavab 28 oktyabr 2011-ci il tarixində saat 04:04 - da Stoyan tərəfindən verilmişdir

Cavabınızı qınayıram, digərini görürəm.

Tipik olaraq, bir sintaksis şablonu olmayan bir modul şablonu (CMS cavabına bax) kifayət qədər yaxşıdır. Bununla belə, təklünün xüsusiyyətlərindən biri, obyektin lazım olduğu qədər başlamasının təxirə salınmasıdır. Modul şablonunda bu xüsusiyyət yoxdur.

Mənim təklifim (CoffeeScript):

 window.singleton = (initializer) -> instance = undefined () -> return instance unless instance is undefined instance = initializer() 

JavaScript-də tərtib olunan nədir:

 window.singleton = function(initializer) { var instance; instance = void 0; return function() { if (instance !== void 0) { return instance; } return instance = initializer(); }; }; 

Sonra aşağıdakıları edə bilərik:

 window.iAmSingleton = singleton(function() {  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 
7
03 нояб. cavab 03 noyabr tarixində skalee verilir. 2011-11-03 01:45 '11 saat 01:45 'də 2011-11-03 01:45

Bu nümunəni JavaScript Şablonlarından əldə etdim Stoyan Stefanov kodlaşdırma və dizayn nümunələri ilə ən yaxşı tətbiqləri yaratmaq , əgər birbaşa singleton kimi bir neçə sadə tətbiqatma sinifinə ehtiyac varsa, aşağıdakı funksiyadan istifadə edə bilərsiniz:

 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 // ie: this.someProperty = 0; this.someMethod = function() { //Some action here }; }; }()); 

Və bu nümunəni test nümunəsi ilə sınayaraq test edə bilərsiniz:

 //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 

Bu yanaşma bütün test nümunələrini keçirir, prototip genişlənməsindən istifadə edərkən xüsusi statik tətbiq müvəffəqiyyətsiz olar (düzəldilə bilər, ancaq asan olmayacaq) və ictimaiyyətin statik tətbiqi daha az uyğundur, çünki nümunə ictimaiyyət üçün açıqdır.

jsFiddly demo.

6
21 янв. Cavab 21-cü Khamidulla tərəfindən verilir 2014-01-21 09:44 '14 at 09:44 2014-01-21 09:44

Qısa cavab:

JavaScript-nin qeyri-blockinq xarakterindən görə, JavaScript-dəki singletonlar həqiqətən çirkin istifadə edirlər. Qlobal dəyişənlər bütün tətbiqlər vasitəsilə də bir nümunə verəcəkdir, bu geri çağırışlar olmadan da, modul şablonu interfeysin arxasında gizlənməyi gizlədir. Cavabına baxın @CMS.

Ancaq bir təkliğa ehtiyacınız olduğundan ...

 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); } }; }; 

İstifadə edin:

 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(); }); 

Şərhlər:

Singletons bütün ərizə boyunca birdən çox surəti verir: onların başlanğıc ilk istifadə qədər gecikdirilir. Bu, başlanğıcın bahalı olduğu obyektlərlə məşğul olduqda həqiqətən böyük bir şeydir. Pahalı odur ki, I / O deməkdir və I / O JavaScript-də hər zaman geri çağırışlar deməkdir.

Bir instance = singleton.getInstance() verən cavablara etiqad etməyin instance = singleton.getInstance() interfeysi, hamısı nöqtəni qaçır.

Nümunə hazır olduqda bir geri çağırışı qəbul etməzlərsə, başlatıcı I / O yerinə yetirdikdə işləməyəcəklər.

Bəli, çağırışlar həmişə bir obyekt çağırışını dərhal qaytaran funksiya çağırışından daha sərt görünür. Ancaq yenə: I / O etdiyiniz zaman geri çağırışlar məcburidir. Hər hansı bir I / O əməliyyatı etmək istəmirsinizsə, proqram yaratdıqda nümunələri yaratmaq bunu kifayət qədər ucuz edir.

Məsələn, ucuz başlanğıc:

 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 reassign this property"); inst.property = "new value"; }); simple(function(inst) { console.log("Access 2"); console.log("Current property value: " + inst.property); }); 

Məsələn 2, I / O istifadə edərək başlatma:

Bu nümunədə setTimeout bəzi bahalı I / O əməliyyatlarına səbəb olur. Bu, JavaScript-dəki singletones həqiqətən geri çağırışlar lazımdır səbəb göstərir.

 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 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."); 
5
18 окт. 18 aylıq skalee cavabı verildi . 2013-10-18 23:36 '13, saat 11:36 'da 2013-10-18 23:36

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 
5
12 сент. Cavab 12 sentyabrda Xaqron tərəfindən verilir . 2017-09-12 22:53 '17 saat 10:53 'da 2017-09-12 22:53

Hesab edirəm ki, javascript proqramında ən təmiz yolu tapdım, ancaq bir növ xəyalma lazımdır. Bu fikri "javascript yaxşı hissələri" kitabında iş üsulundan aldım.

Yeni bir söz istifadə etmək əvəzinə, bu sinfi yarada bilərsiniz:

 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; } 

Yuxarıdakı bir obyektin bir nümunəsini söyləyə bilərsiniz:

 var objInst = Class(); // !!! NO NEW KEYWORD 

İndi bu iş üsulunu nəzərə alaraq, aşağıdakı kimi bir təklik yarada bilərsiniz:

 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 }; }(); 

İndi kopyanızı zəng edərək əldə edə bilərsiniz

 var obj = ClassSingleton.getInstance(); 

Hesab edirəm ki, bu, ən asan yoldur, çünki tam "sinif" hətta mövcud deyildir.

5
02 сент. Cavab David tərəfindən verilir 02 İyul 2014-09-02 15:13 '14 da 15:13 2014-09-02 15:13

Heç kimin onu seçmədiyindən əmin deyilsiniz, ancaq sadəcə edə bilərsiniz:

 var singleton = new (function() { var bar = 123 this.foo = function() { // whatever } })() 
4
22 июля '13 в 6:15 2013-07-22 06:15 Cavab Derek Chiang tərəfindən 22 iyul 2013-cü il saat 6:15 radələrində 2013-07-22 06:15

Bu sənəddə Addi Osmani kitabının "JavaScript Design Patterns araşdırılması" kitabından ən dəqiq cavab verilməlidir.

4
10 окт. cavab verildi . 2017-10-10 10:28 '17 saat 10:28 'da 2017-10-10 10:28

@CMS və @zzzzBov gözəl cavablar aldılar, amma PHP / Zend Framework'dən node.js-in çətin işinə köçdüklərimə əsasən öz şərhimi əlavə etdilər.

Aşağıdakı şərh kodu aşağıdakı tələblərə əsaslanır:

  • funksiya obyektinin yalnız bir nüsxəsi örnək edilə bilər
  • instansiya ictimaiyyətə açıq deyil və yalnız ictimai metoddan istifadə edilə bilər.
  • konstruktor ictimaiyyət deyil və yalnız mövcud olan bir hadisə olmadıqda yaradıla bilər.
  • Konstruktiv bəyannaməsi prototip zəncirinin dəyişdirilməsinə imkan verməlidir. Bu, konstruktorun digər prototiplərdən miras alınmasına və nümunəyə "ictimai" üsulları təklif etməyə imkan verəcəkdir.

Mənim kodu @zzzzBov-a çox oxşardır, istisna etmək üçün PHP və ya oxşar dil ilə gələnlərə köməkçi olmalıdır ki, qurucuda prototiplər zəncirini və əlavə şərhləri əlavə etmişəm, ancaq ənənəvi OOP prototipi Javascriptlərə çevrilir. Bu "asan" ola bilməz, amma bu ən uyğun hesab edirəm.

 // 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 the same instance as 'a' 

Xahiş edirik, texniki cəhətdən öz-özünə imzalanmış anonim funksiyanın özü @CMS tərəfindən verilən kodda göstərildiyi kimi bir təkdir. Buradakı yeganə növdür ki, anonimator dizayneri özü qurucu prototiplərinin zəncirini dəyişdirmək mümkün deyil.

PHP və ya Java kimi "ictimai" və "şəxsi" Javascriptlara tətbiq edilməyən konsepsiyaların nəzərə alınmamasını unutmayın. Amma eyni təsiri Javascript funksional sahəsinin əlçatanlıq qaydalarını istifadə edərək əldə etdik.

4
17 сент. Cavab verilmiş talentedmrjones Sep 17 2012-09-17 00:38 '12 at 0:38 2012-09-17 00:38

Mənə 5 sikkə qoya bilərəm. Məsələn, bir konstruktor funksiyası var.

 var A = function(arg1){ this.arg1 = arg1 }; 

Yalnız bu CF tərəfindən yaradılan hər bir obyekt eyni olacaq.

 var X = function(){ var instance = {}; return function(){ return instance; } }(); 

Test et

 var x1 = new X(); var x2 = new X(); console.log(x1 === x2) 
2
03 дек. Cavab Andrii Olenchenko tərəfindən verilir 03 dekabr . 2015-12-03 10:25 '15, saat 10:25 'da

Nöqtədə növbəti iş v6

 class Foo { constructor(msg) { if (Foo.singleton) { return Foo.singleton; } this.msg = msg; Foo.singleton = this; return Foo.singleton; } } 

Test edirik:

 const f = new Foo('blah'); const d = new Foo('nope'); console.log(f); // => Foo { msg: 'blah' } console.log(d); // => Foo { msg: 'blah' } 
2
26 дек. Cavab Daniel 26 dekabrda verilir. 2017-12-26 11:53 '17 'da 11:53' də 2017-12-26 11:53

Bir java ssenarisində bir tək nümunəni izah etmək üçün sadə bir nümunə.

  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(); 
2
24 сент. Sheo Dayal Singh tərəfindən verilib cavab 24 Sep 2017-09-24 20:20 '17 saat 20:20 'da 2017-09-24 20:20

Sadə Singleton nümunəsi olan aşağıdakıları tapdım: yeni bir operator istifadə edərək, bir funksiyaya daxil olan dərhal mövcud olur və obyektin əlifbasını geri qaytarmağın zəruriliyini aradan qaldırır:

2
16 февр. Cavab 16 fevralda Mark tərəfindən verilir. 2018-02-16 08:40 '18 saat 08:40 'da 2018-02-16 08:40' də

Modul düzeni: "daha oxunaqlı bir üslubda". Hansı üsulların ictimaiyyətə və şəxsi olduğuna asanlıqla baxa bilərsiniz.

 var module = (function(_name){  var _local = { name : _name, flags : { init : false } } function init(){ _local.flags.init = true; } function imaprivatemethod(){ alert("hi im a private method"); }  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"); 

İndi məsələn ictimai üsullardan istifadə edə bilərsiniz

modul method.method2 (); // -> Mən şəxsi metodu ictimai metoddan xəbərdar edirəm ("salam şəxsi üsul")

http://jsfiddle.net/ncubica/xMwS9/

1
09 июля '13 в 18:34 2013-07-09 18:34 Cavab ncubica tərəfindən 09.07.2013 18:34 tarixində verilir
 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 
1
23 авг. Pol Sweatte tərəfindən verilən cavabı 23 Av . 2013-08-23 08:48 '13 at 8:48 2013-08-23 08:48

Bunu, aşağıda bu nümunədə olduğu kimi, dekorativlər ilə edə bilərsiniz: TypeScript üçün:

 class YourClass { @Singleton static singleton() {} } function Singleton(target, name, descriptor) { var instance; descriptor.value = () => { if(!instance) instance = new target; return instance; }; } 

Sonra aşağıdakıları istifadə edirsiniz:

 var myInstance = YourClass.singleton(); 

Bu yazı zamanı JavaScript maşınlarında dekoratörler asanlıqla istifadə edilə bilməzdi. JavaScript işləmə müddətinizin həqiqətən daxil edilmiş və ya Babel və TypeScript kimi kompilyatorlardan istifadə edən dekorativlər olduğundan əmin olmalısınız.

Həmçinin təklin nümunəsinin "tənbəl" olaraq yaradıldığını qeyd edin, yəni. yalnız ilk dəfə istifadə edərkən yaradılıb.

1
26 сент. cavab Vad 26 sep verilir . 2016-09-26 14:22 '16 saat 14:22 'də 2016-09-26 14:22' də

Bu üsulla əlaqədar olaraq, yalnız sinif yeni olmağına əmin olun.

Belə ki, getInstance istifadə edə bilərsiniz, bir sinif devralmaq üçün bir prototip zəncir istifadə edə bilərsiniz, bu normal bir sinifdir, lakin getInstance bir nümunə almaq istəyirsə, yalnız getInstance istifadə getInstance

 function CA() { if(CA.instance) { throw new Error('can not new this class'); }else{ CA.instance = this; } }  CA.instance = null;  CA.getInstance = function() { return CA.instance; } CA.prototype =  { 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(); 

Məsələnin bir üzvünü açıqlamaq istəmirsinizsə, sadəcə onu bağlanın.

1
29 июля '13 в 15:01 2013-07-29 15:01 cavab 29 iyul '13, saat 15:01 'də verilir 2013-07-29 15:01

Singleton:

Sınıfın yalnız bir örneğine malik olmasını təmin edin və bunun üçün bir qlobal giriş nöqtəsi təmin edin.

Singleton nümunəsi müəyyən bir obyektin nümunələrinin sayını yalnız birinə məhdudlaşdırır. Bu tək nümunəyə təkli deyilir.

  • unikal bir nümunə qaytaran getInstance () müəyyən edir.
  • Məsələn obyektin yaradılması və idarə olunması üçün cavabdehdir.

Singleton obyekti dərhal anonim funksiya kimi həyata keçirilir. Bu funksiya parantezlə sarıldıqdan sonra dərhal yerinə yetirilir və sonra iki əlavə parantez. Anonim ad deyil, çünki adı yoxdur.

Nümunə proqramı

1
18 июля '17 в 10:35 2017-07-18 10:35 Cavab Mohideen ibn Mohammed tərəfindən 18 İyul 18 'də saat 10:35' da 2017-07-18 10:35

Bu da deyil?

 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(); 
1
24 мая '15 в 16:29 2015-05-24 16:29 Cavab Nawal tərəfindən 24 May 'da 16:29' də verilir 2015-05-24 16:29

Aşağıda bir tək nümunəsi tətbiq etmək üçün keçidimin bir parçasıdır. Müsahibə zamanı mənim başıma gəldi və mən bir yerə qapalı qaldığımı hiss etdim.

  //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; } }; }  

то же самое можно найти на моей странице gist

1
ответ дан curioussam 23 авг. '13 в 20:27 2013-08-23 20:27

Что случилось с этим?

 function Klass() { var instance = this; Klass = function () { return instance; } } 
1
ответ дан Manav 04 июля '12 в 5:40 2012-07-04 05:40

Мне понадобилось несколько синглетонов с:

  • ленивая инициализация
  • начальные параметры

и именно так я и придумал:

 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 должен быть массивом для работы, поэтому, если у вас есть пустые переменные, просто перейти в []

  • Я использовал объект окна в функции, но я мог бы пройти в параметре, чтобы создать свою собственную область

  • имя и конструктивные параметры - это только строка для работы окна [], но с некоторыми простыми проверками типов, window.name и window.construct также возможны.

1
ответ дан fred 29 мая '12 в 11:30 2012-05-29 11:30

Вы можете вернуть один и тот же экземпляр в каждом new исполнении -

 function Singleton() { // lazy if (Singleton.prototype.myInstance == undefined) { Singleton.prototype.myInstance = { description: "I am the instance"}; } return Singleton.prototype.myInstance; } a = new Singleton(); b = new Singleton(); console.log(a); // { description: "I am the instance"}; console.log(b); // { description: "I am the instance"}; console.log(a==b); // true 
0
ответ дан URL87 17 окт. '18 в 10:57 2018-10-17 10:57

Основной ключ - это значение Undertand Closure за этим. Таким образом, свойство внутри внутренней функции будет закрыто с помощью закрытия.

var Singleton = function() {var instance;

  function init() { function privateMethod() { console.log("private via closure"); } var privateVariable = "Private Property"; var privateRandomNumber = Math.random();// this also private return { getRandomNumber: function () { // access via getter in init call return privateRandomNumber; } }; }; return { getInstance: function () { if (!instance) { instance = init(); } return instance; } }; 

};

0
ответ дан Siddhartha 06 апр. '17 в 22:14 2017-04-06 22:14

Вы не сказали "в браузере". В противном случае вы можете использовать модули NodeJS . Эти одинаковы для каждого вызова require . Əsas nümunə:

Содержимое foo.js:

 const circle = require('./circle.js'); console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); 

Содержимое circle.js:

 const PI = Math.PI; exports.area = (r) => PI * r * r; exports.circumference = (r) => 2 * PI * r; 

Обратите внимание, что вы не можете получить доступ к circle.PI , так как он не экспортируется.

Хотя это не работает в браузере, оно просто и чисто.

0
ответ дан serv-inc 23 июня '16 в 0:09 2016-06-23 00:09

Я считаю, что это самый простой/самый чистый и интуитивно понятный способ, хотя для этого требуется ES7:

 export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } } 

Исходный код: adam-bien.com

0
ответ дан Alt Eisen 25 авг. '17 в 6:50 2017-08-25 06:50

Singleton в 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(); cnosole.log(obj1===obj2); //check for type and value. 
0
ответ дан user2756335 23 апр. '17 в 16:11 2017-04-23 16:11
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос