JavaScript'te singleton desenini uygulamanın en basit / en temiz yolu nedir?
JavaScript'te singleton desenini uygulamanın en basit / en temiz yolu nedir?
Yanıtlar:
Bence en kolay yol basit bir nesne değişmezi bildirmektir:
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
Singleton örneğinizde özel üyeler istiyorsanız, şöyle bir şey yapabilirsiniz:
var myInstance = (function() {
var privateVar = '';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accessible here
},
publicMethod2: function () {
}
};
})();
Bu modül deseni olarak adlandırılmıştır , temel olarak kapakların kullanımından yararlanarak özel üyeleri bir nesne üzerinde kapsüllemenizi sağlar .
GÜNCELLEME: Singleton nesnesinin değiştirilmesini önlemek istiyorsanız , ES5 yöntemini kullanarak bunu dondurabileceğinizi eklemek isterim Object.freeze
.
Bu, nesneyi değiştirilemez hale getirecek, yapısında ve değerlerinde herhangi bir değişiklik yapılmasını önleyecektir.
Ek olarak, ES6 kullanıyorsanız, ES Modüllerini kullanarak bir singletonu kolayca temsil edebileceğinizi ve modül kapsamındaki değişkenleri bildirerek özel durumu bile tutabileceğinizi belirtmek isterim :
// my-singleton.js
const somePrivateState = []
function privateFn () {
// ...
}
export default {
method1() {
// ...
},
method2() {
// ...
}
}
Ardından, tek nesneyi kullanmak için içe aktarabilirsiniz:
import myInstance from './my-singleton.js'
// ...
publicMethod1
arayabilirsin publicMethod2
?
getInstance
yöntem ve özel bir yapıcı içeren birçok uygulamayı hatırlıyorum- ancak IMO, bu tek bir nesne oluşturmak için en "basit" yoldur Javascript'te ve sonunda aynı amaca ulaşır - tek bir nesne, tekrar başlatamazsınız (yapıcı yok, sadece bir nesne) -. Bağlı kodu hakkında, bazı sorunları var takas a
ve b
değişken bildirimlerini ve testi a === window
. Şerefe.
Bence en temiz yaklaşım şudur:
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;
}
};
})();
Daha sonra, işlevi şu şekilde çağırabilirsiniz:
var test = SingletonFactory.getInstance();
delete instance.constructor
:x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
Tek bir kalıbın yerine kullanılan modül kalıbına katıldığımdan emin değilim. Çoğunlukla gereksiz oldukları yerlerde kullanılan ve kötüye kullanılan singletonları sık sık gördüm ve modül deseninin programcıların aksi takdirde singleton kullanacağı birçok boşluğu doldurduğundan eminim, ancak modül deseni singleton değildir .
var foo = (function () {
"use strict";
function aPrivateFunction() {}
return { aPublicFunction: function () {...}, ... };
}());
Modül şablonunda başlatılan her şey Foo
bildirildiğinde gerçekleşir. Ek olarak modül modeli, daha sonra birçok kez başlatılabilen bir yapıcıyı başlatmak için kullanılabilir. Modül deseni birçok iş için doğru araç olsa da, tek bir tona eşdeğer değildir.
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();
}
uzun biçim, modül modeli kullanarak
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 deseninin her iki sürümünde de yapıcı kendisi erişimci olarak kullanılabilir:
var a,
b;
a = new Foo(); //constructor initialization happens here
b = new Foo();
console.log(a === b); //true
Yapıcıyı bu şekilde kullanmakta kendinizi rahat hissetmiyorsanız, if (instance)
ifadeye bir hata atabilir ve uzun formu kullanmaya devam edebilirsiniz:
var a,
b;
a = Foo.getInstance(); //constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); //true
Ayrıca singleton desen örtük yapıcı işlev desen iyi uyuyor belirtmek gerekir:
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 = {}
bu tanıma uymuyor.
var singleton = {}
Javascript ile singleton uygulama şeklidir .
İçinde 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
alana sahip olsaydı mantıklı olurdu . Halen (olarak instance
ayarlandığı gibi this
) bu sınıfın başka alanları da olabilir ve donma mantıklı değildir.
V6 düğümünde aşağıdaki işler
class Foo {
constructor(msg) {
if (Foo.singleton) {
return Foo.singleton;
}
this.msg = msg;
Foo.singleton = this;
return Foo.singleton;
}
}
Test ediyoruz:
const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }
ES6'da bunu yapmanın doğru yolu:
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
Veya, ikinci örnek oluşturmada bir hatanın atılmasını istemiyorsanız, yalnızca aşağıdaki örneği döndürebilirsiniz:
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
Ve arasında teknik bir fark yoktur _instance
. Programlama dillerinde sadece alt çizgi ile eklenmiş özel değişkenleri adlandırdığımız bir adlandırma kuralıdır . Kodunuzun çalışmamasının sebebinin this.instance
bunun yerine kullandığınızdan MyClass.instance
Bir kedinin derisini atmanın birden fazla yolu vardır :) Zevkinize veya özel ihtiyacınıza bağlı olarak önerilen çözümlerden herhangi birini uygulayabilirsiniz. Şahsen CMS'nin ilk çözümünü mümkün olduğunda (gizliliğe ihtiyacınız olmadığında) kullanıyorum. Soru en basit ve en temiz hakkında olduğundan, kazanan bu. Ya da:
var myInstance = {}; // done!
Bu (blogumdan alıntı) ...
var SingletonClass = new function() {
this.myFunction() {
//do stuff
}
this.instance = 1;
}
çok mantıklı değil (blog örneğim de öyle değil) çünkü herhangi bir özel değişkene ihtiyaç duymaz, bu yüzden hemen hemen aynıdır:
var SingletonClass = {
myFunction: function () {
//do stuff
},
instance: 1
}
this.f(){}
Cevabımı reddediyorum, diğerini görüyorum .
Genellikle tekli desen DEĞİL olan modül modeli (bkz. CMS cevabı) yeterince iyidir. Bununla birlikte, singleton'un özelliklerinden biri, nesneye ihtiyaç duyulana kadar başlatılmasının gecikmesidir. Modül deseninde bu özellik yoktur.
Benim önerim (CoffeeScript):
window.singleton = (initializer) ->
instance = undefined
() ->
return instance unless instance is undefined
instance = initializer()
JavaScript'te bunu derleyen:
window.singleton = function(initializer) {
var instance;
instance = void 0;
return function() {
if (instance !== void 0) {
return instance;
}
return instance = initializer();
};
};
Sonra aşağıdakileri yapabilirim:
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'in engellenmeyen doğası nedeniyle, JavaScript'teki Singletons gerçekten çirkin. Global değişkenler, tüm bu geri çağrılar olmadan da tüm uygulama boyunca size bir örnek verecektir, modül kalıbı arayüzün arkasındaki içleri nazikçe gizler. @CMS cevabına bakınız.
Ama, bir singleton istediğin için ...
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);
}
};
};
Kullanımı:
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();
});
Teklitonlar tüm uygulama boyunca size birden fazla örnek verir: ilk kullanıma kadar başlatılmaları ertelenir. Başlangıcı pahalı olan nesnelerle uğraşırken bu gerçekten büyük bir şey. Pahalı genellikle G / Ç anlamına gelir ve JavaScript G / Ç her zaman geri arama anlamına gelir.
Size arayüz gibi cevaplar güvenmiyorum instance = singleton.getInstance()
, hepsi noktası özledim.
Örnek hazır olduğunda çalıştırılmak üzere geri çağrı almazlarsa, başlatıcı G / Ç yaptığında çalışmazlar.
Evet, geri çağrılar her zaman nesne örneğini hemen döndüren işlev çağrısından daha çirkin görünür. Ama tekrar: I / O yaptığınızda geri aramalar zorunludur. Herhangi bir G / Ç yapmak istemiyorsanız, başlatma işlemi program başlangıcında yapacak kadar ucuzdur.
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);
});
Bu örnekte setTimeout
bazı pahalı G / Ç işlemleri yapılıyor. Bu, JavaScript'teki singletonların neden gerçekten geri arama gerektirdiğini gösterir.
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.");
Bu örneği JavaScript Kalıplarından aldım Kodlama ve Tasarım Kalıpları ile Daha İyi Uygulamalar Oluşturun Stoyan Stefanov'un kitabına göre, singltone nesnesi gibi basit bir uygulama sınıfına ihtiyacınız olması durumunda hemen aşağıdaki işlevi kullanabilirsiniz:
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
};
};
}());
Ve bu örneği aşağıdaki test durumunu kullanarak kontrol edebilirsiniz:
//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
Prototip uzantısı kullanıldığında (sabit olabilir ancak basit olmayacak) özel statik uygulama başarısız olurken ve örnek nedeniyle halka daha az tavsiye edilen genel statik uygulama başarısız olurken, bu yaklaşımlar tüm test durumlarını geçer.
JavaScript'te programlamanın en temiz yolunu bulduğumu düşünüyorum, ancak biraz hayal gücüne ihtiyacınız olacak. Bu fikri "iyi parçaları javascript" kitabındaki bir çalışma tekniğinden aldım.
Yeni anahtar kelimeyi kullanmak yerine, aşağıdaki gibi bir sınıf oluşturabilirsiniz:
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;
}
Yukarıdaki nesneyi şunu söyleyerek başlatabilirsiniz:
var objInst = Class(); // !!! NO NEW KEYWORD
Şimdi bu çalışma yöntemini göz önünde bulundurarak şöyle bir tekton oluşturabilirsiniz:
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 };
}();
Şimdi örneğinizi arayarak alabilirsiniz
var obj = ClassSingleton.getInstance();
Tam "Sınıf" bile erişilebilir değil çünkü bu en güzel yolu olduğunu düşünüyorum.
@CMS ve @zzzzBov harika cevaplar verdiler, ancak sadece tekil kalıpların yaygın olduğu PHP / Zend Framework'ten ağır node.js geliştirmeye taşındığımı temel alarak kendi yorumumu eklemek için.
Aşağıdaki, dokümante edilmiş kod aşağıdaki gereksinimlere dayanmaktadır:
Kodum, yapıcıya bir prototip zinciri ve PHP veya benzer bir dilden gelenlerin geleneksel OOP'yi Javascripts prototipik doğasına çevirmesine yardımcı olacak daha fazla yorum eklediğim için @ zzzzBov'unkine çok benziyor. "En basit" olmayabilir ama en uygun olduğuna inanıyorum.
// 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'
Teknik olarak, kendi kendini yürüten anonim işlevin, @CMS tarafından sağlanan kodda güzel bir şekilde gösterildiği gibi bir Singleton olduğunu unutmayın. Buradaki tek yakalama, kurucunun anonim olması durumunda kurucunun prototip zincirini değiştirmenin mümkün olmamasıdır.
Javascript için, “public” ve “private” kavramlarının PHP veya Java'da olduğu gibi geçerli olmadığını unutmayın. Ancak Javascript'in işlevsel kapsam kullanılabilirliği kurallarından yararlanarak aynı etkiyi elde ettik.
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
Kimsenin bunu neden büyütmediğinden emin değilim, ancak şunları yapabilirsiniz:
var singleton = new (function() {
var bar = 123
this.foo = function() {
// whatever
}
})()
En açık cevap Addy Osmani'nin JavaScript Tasarım Desenlerini Öğrenmek kitabından bu olmalıdır.
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 gerektirmesine rağmen bunun en basit / en temiz ve en sezgisel yol olduğuna inanıyorum:
export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } }
Kaynak kodu: adam-bien.com
new Singleton()
5 paramı koyabilir miyim. Bir yapıcı işlevi var, ex.
var A = function(arg1){
this.arg1 = arg1
};
Yapmam gereken sadece bu CF tarafından oluşturulan her nesnenin aynı olacağı.
var X = function(){
var instance = {};
return function(){ return instance; }
}();
Ölçek
var x1 = new X();
var x2 = new X();
console.log(x1 === x2)
Kullanarak, çünkü en kolay Singleton deseni olmak için aşağıdaki buldum yeni operatörünü yapar bu bir nesne değişmezi dönmek için ihtiyacı ortadan kaldırarak, işlev içinde hemen kullanılabilir:
var singleton = new (function () {
var private = "A private value";
this.printSomething = function() {
console.log(private);
}
})();
singleton.printSomething();
Javascript tekil desen açıklamak için basit bir örnek.
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();
Ben ile birkaç singleton gerekli:
ve işte ben de bunu buldum:
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;
}
Boş değişkenleriniz varsa, bunun çalışması için argümanlar Array olmalıdır. []
İşlevde pencere nesnesi kullandım, ancak kendi kapsamımı oluşturmak için bir parametrede geçebilirdim
name ve construct parametreleri yalnızca [] penceresinin çalışması için Dize'dir, ancak bazı basit tip denetimi ile window.name ve window.construct da mümkündür.
Bu şekilde, sadece sınıf tekrar yeni olamaz emin olun.
Bu sayede instanceof
op'u kullanabilirsiniz , ayrıca sınıfı devralmak için prototip zincirini kullanabilirsiniz, bu normal bir sınıftır, ancak yeni bir şey olamaz, eğer örneği almak istiyorsanızgetInstance
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();
Eğer instance
üyeyi ifşa etmek istemiyorsanız, üyeyi kapatmanız yeterlidir.
Aşağıda, tek bir desen uygulamak için yürüdüğüm pasaj var. Bu bir röportaj sürecinde bana geldi ve bunu bir yerde yakalamam gerektiğini hissettim.
/*************************************************
* 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
*******************************************************************/
aynısını gist sayfamda da bulabilirsiniz
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 için aşağıdaki örnekte olduğu gibi dekoratörlerle yapabilirsiniz:
class YourClass {
@Singleton static singleton() {}
}
function Singleton(target, name, descriptor) {
var instance;
descriptor.value = () => {
if(!instance) instance = new target;
return instance;
};
}
Sonra singletonunuzu şöyle kullanın:
var myInstance = YourClass.singleton();
Bu yazı itibariyle, dekoratörler JavaScript motorlarında mevcut değildir. JavaScript çalışma zamanınızın dekoratörlerinin gerçekten etkinleştirildiğinden emin olmanız veya Babel ve TypeScript gibi derleyiciler kullanmanız gerekir.
Ayrıca singleton örneğinin "tembel" olarak oluşturulduğunu, yani yalnızca ilk kez kullandığınızda oluşturulduğunu unutmayın.
Modül düzeni: "daha okunabilir tarzda". Hangi yöntemlerin kamu ve hangilerinin özel olduğunu kolayca görebilirsiniz
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");
şimdi gibi halka açık yöntemleri kullanabilirsiniz
module.method2 (); // -> Genel yöntem uyarısı üzerinden özel bir yöntem arıyorum ("hi im a private method")
Singleton:
Bir sınıfın yalnızca bir örneğinin bulunduğundan emin olun ve ona bir genel erişim noktası sağlayın.
Tek Ton Deseni, belirli bir nesnenin örnek sayısını yalnızca biriyle sınırlar. Bu tek örneğe singleton denir.
Singleton nesnesi, anonim bir işlev olarak uygulanır. İşlev hemen parantez içine alınır ve ardından iki ek parantez eklenir. Anonim olarak adlandırılır çünkü bir adı yoktur.
Örnek Program,
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()
Benim için En Basit / En Temiz, tartışmanın Java sürümünde çok tartışıldığı gibi sadece anlamak ve çan ve ıslık olmaması anlamına gelir:
Java'da tek tonlu bir desen uygulamanın etkili bir yolu nedir?
Benim açımdan orada en basit / en temiz en uygun cevap:
https://stackoverflow.com/a/70824/1497139
Ve sadece kısmen JavaScript'e çevrilebilir. Javascript'teki farklardan bazıları:
Ancak en son ECMA sözdizimi verildiğinde aşağıdakilere yaklaşmak mümkündür:
JavaScript sınıfı örneği olarak singleton kalıbı
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;
}
}
Örnek Kullanım
console.log(Singleton.getInstance().field1);
console.log(Singleton.getInstance().field2);
Örnek Sonuç
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;
}
Sınıflara giriyorsanız:
class Once {
constructor() {
return this.constructor.instance || (this.constructor.instance = this);
}
}
class Application extends Once {
constructor(name) {
super();
this.name = name;
}
}
Ölçek:
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
Sınıfları kullanmak istiyorsanız:
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);
Yukarıdakiler için çıktı:
console.log(x.name,x.age,y.name,y.age) // s 1 s 1
Singleton işlevini kullanarak yazmanın başka bir yolu
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);
Yukarıdakiler için çıktı:
console.log(a.name,a.age,b.name,b.age)// s 1 s 1