La façon la plus simple et la plus propre d'implémenter singleton dans JavaScript?

Quelle est la manière la plus simple/la plus propre d'implémenter le modèle singleton en JavaScript?

255
demandé sur RzR 2009-09-26 00:05:51

30 réponses

je pense que la façon la plus facile est de déclarer un objet simple littéral:

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

si vous voulez des membres privés sur votre instance singleton, vous pouvez faire quelque chose comme ceci:

var myInstance = (function() {
  var privateVar = '';

  function privateMethod () {
    // ...
  }

  return { // public interface
    publicMethod1: function () {
      // all private members are accesible here
    },
    publicMethod2: function () {
    }
  };
})();

cela a été appelé le module pattern , il vous permet essentiellement d'encapsuler des membres privés sur un objet, en profitant de l'utilisation de fermetures .

283
répondu CMS 2009-09-25 20:15:48

je pense que le plus propre de l'approche est quelque chose comme:

var SingletonClass = (function(){
    function SingletonClass() {
        //do stuff
    }
    var instance;
    return {
        getInstance: function(){
            if (instance == null) {
                instance = new SingletonClass();
                // Hide the constructor so the returned objected can't be new'd...
                instance.constructor = null;
            }
            return instance;
        }
   };
})();

ensuite, vous pouvez invoquer la fonction comme

var test = SingletonClass.getInstance();
151
répondu sebarmeli 2012-10-18 23:39:07

Je ne suis pas sûr que je suis d'accord avec le modèle de module étant utilisé comme un remplacement pour un modèle singleton. J'ai souvent vu des Singleton utilisés et abusés dans des endroits où ils sont tout à fait inutiles, et je suis sûr que le modèle de module remplit de nombreuses lacunes où les programmeurs utiliseraient autrement un singleton, mais le modèle de module est et non un singleton.

motif de module:

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

tout initialisé dans le module le motif se produit lorsque Foo est déclaré. De plus, le module pattern peut être utilisé pour initialiser un constructeur, qui pourrait alors être instancié plusieurs fois. Bien que le modèle de module soit le bon outil pour de nombreux travaux, il n'est pas équivalent à un singleton.

pattern singleton:

forme courte
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();
}
forme longue, utilisant le modèle de module
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;
}());

dans les deux versions du Singleton pattern que j'ai fourni, le constructeur lui-même peut être utilisé comme accesseur:

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

si vous ne vous sentez pas à l'aise d'utiliser le constructeur de cette façon, vous pouvez jeter une erreur dans la déclaration if (instance) , et s'en tenir à l'utilisation de la forme longue:

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

je dois aussi mentionner que le modèle singleton s'inscrit bien avec le modèle de fonction implicite du constructeur:

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
91
répondu zzzzBov 2012-10-09 00:20:28

il y a plus d'une façon de dépecer un chat :) selon votre goût ou besoin spécifique, vous pouvez appliquer n'importe laquelle des solutions proposées. Je suis personnellement pour la première solution DE CMS chaque fois que possible (quand vous n'avez pas besoin de la vie privée). Puisque la question était sur le plus simple et le plus propre, c'est le gagnant. Ou même:

var myInstance = {}; // done!

Ce (citation de mon blog) ...

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

n'a pas beaucoup de sens (mon exemple de blog n'a pas non plus) parce que il n'a pas besoin de voitures privées, donc c'est à peu près la même chose que:

var SingletonClass = { 
    myFunction: function () { 
        //do stuff 
    },
    instance: 1 
}
8
répondu Stoyan 2011-06-28 01:04:55

je railler ma réponse, voir mon autre .

habituellement le modèle de module (voir la réponse DE CMS) qui n'est pas le modèle singleton est assez bon. Cependant, l'une des caractéristiques de singleton est que son initialisation est retardée jusqu'objet est nécessaire. Le modèle de Module ne possède pas cette caractéristique.

ma proposition (CoffeeScript):

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

qui a compilé à cela en JavaScript:

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

alors je peux faire ce qui suit:

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
7
répondu skalee 2017-05-23 12:03:05

j'ai eu cet exemple de motifs JavaScript Construire de meilleures Applications avec des modèles de codage et de conception Par Stoyan Stefanov l 'livre dans le cas où vous avez besoin d'une classe d'implémentation simple comme objet singltone, vous pouvez utiliser la fonction immédiate comme suit:

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

et vous pouvez vérifier cet exemple en suivant le test case:

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

cette approche réussit tous les cas d'essai tandis que la mise en œuvre privée statique échouera lorsque l'extension prototype est utilisé (il peut être fixé, mais il ne sera pas simple) et la mise en œuvre statique publique moins souhaitable en raison de l'instance est exposée au public.

jsfiddly demo.

6
répondu Khamidulla 2014-01-21 06:54:35

courte réponse:

parce que la nature non-bloquante de JavaScript, les Singletons en JavaScript sont vraiment moches dans l'utilisation. Les variables globales vous donneront une instance à travers l'ensemble de l'application aussi sans toutes ces callbacks, le motif du module cache délicatement les internes derrière l'interface. Voir la réponse de @CMS.

mais, puisque vous vouliez un singleton ...

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

};

Utilisation:

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

explication:

Singletons vous donnent plus qu'une seule instance à travers l'application entière: leur initialisation est retardée jusqu'à la première utilisation. C'est vraiment important quand vous vous occupez d'objets dont l'initialisation coûte cher. Cher signifie habituellement I/O et en JavaScript I / O signifie toujours des rappels.

Ne faites pas confiance à des réponses qui vous donnent de l'interface comme instance = singleton.getInstance() , ils sont tous à côté de la question.

S'ils ne le font pas prendre de callback à exécuter lorsqu'une instance est prêt, alors ils ne fonctionnent pas lors de l'initialiseur de ne I/O.

Ouais, les callbacks ont toujours l'air plus moche que les Calls de fonction qui renvoie immédiatement l'instance de l'objet. Mais encore une fois: lorsque vous faites des e/s, les callbacks sont obligatoires. Si vous ne voulez pas faire d'E/S, alors instanciation est assez bon marché pour le faire au démarrage du programme.

exemple 1, initialiseur bon marché:

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

exemple 2, initialisation avec E/S:

dans cet exemple, setTimeout simule une opération d'e/s coûteuse. Ceci illustre pourquoi les singletons en JavaScript ont vraiment besoin de callbacks.

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.");
5
répondu skalee 2013-10-19 09:01:41

je pense que j'ai trouvé le moyen le plus propre de programmer en JavaScript, mais vous aurez besoin d'imagination. J'ai eu cette idée d'une technique de travail dans le livre "javascript les bonnes parties".

au Lieu d'utiliser le nouveau mot-clé, vous pouvez créer une classe comme ceci:

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

vous pouvez instancier l'objet ci-dessus en disant:

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

maintenant, avec cette méthode de travail en tête, vous pourriez créer un singleton comme celui-ci:

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

}();

Maintenant vous pouvez obtenir votre instance en appelant

var obj = ClassSingleton.getInstance();

je pense que c'est le moyen le plus approprié car la" classe " complète n'est même pas accessible.

5
répondu David 2014-09-02 12:18:36

@CMS et @zzzzBov ont tous deux donné des réponses merveilleuses, mais juste pour ajouter ma propre interprétation basée sur mon avoir déménagé dans le noeud lourd.le développement de js à partir du cadre PHP/Zend où les modèles singleton étaient communs.

le code de commentaire ci-dessous est fondé sur les exigences suivantes:

  • une seule instance de l'objet de la fonction peut être instanciée
  • l'instance n'est pas publiquement disponible et accessible uniquement par une méthode publique
  • le constructeur n'est pas accessible au public et ne peut être instancié que s'il n'y a pas déjà une instance disponible
  • la déclaration du constructeur doit permettre la modification de sa chaîne prototype. Cela permettra au constructeur d'hériter d'autres prototypes, et l'offre "publique" méthodes pour l'instance

mon code est très similaire à celui de @zzzzBov sauf que j'ai ajouté une chaîne prototype au constructeur et plus de commentaires qui devraient aider ceux qui viennent de PHP ou un langage similaire traduire OOP traditionnel à la nature prototypique Javascripts. Ce n'est peut-être pas le plus "simple", mais je crois que c'est le plus approprié.

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

notez que techniquement, la fonction anonyme auto-exécutable est elle-même un Singleton comme le montre bien le code fourni par @CMS. Le seul hic ici, c'est qu'il n'est pas possible de modifier la chaîne de prototype du constructeur lorsque le constructeur lui-même est anonyme.

garder à l'esprit que pour Javascript, les concepts de "public" et "privé" ne s'appliquent pas comme ils le font en PHP ou Java. Mais nous avons obtenu le même effet en utilisant les règles de disponibilité de la portée fonctionnelle de Javascript.

4
répondu talentedmrjones 2012-09-16 21:38:46

Je ne sais pas pourquoi personne n'en a parlé, mais vous pourriez le faire:

var singleton = new (function() {
  var bar = 123

  this.foo = function() {
    // whatever
  }
})()
4
répondu Derek Chiang 2013-07-22 03:15:30

Dans 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
4
répondu Xaqron 2017-09-12 19:53:47

la réponse la plus claire devrait être celle-ci du livre Learning JavaScript Design Patterns de 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;
    }
 
  };
 
})();
4
répondu 令狐葱 2017-10-10 07:28:22

puis-je mettre mes 5 pièces. J'ai une fonction constructeur, ex.

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

ce que je dois faire, c'est que chaque objet créé par CE CF sera le même.

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

test

var x1 = new X();
var x2 = new X();
console.log(x1 === x2)
2
répondu Andrii Olenchenko 2015-12-03 07:39:02

les travaux suivants dans le noeud v6

class Foo {
  constructor(msg) {

    if (Foo.singleton) {
      return Foo.singleton;
    }

    this.msg = msg;
    Foo.singleton = this;
    return Foo.singleton;
  }
}

Nous testons:

const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }
2
répondu Daniel 2017-12-26 08:53:54

j'ai trouvé que le suivant est le modèle Singleton le plus facile, parce qu'en utilisant le nouvel l'opérateur rend ce immédiatement disponible dans la fonction, éliminant la nécessité de retourner un objet littéral:

var singleton = new (function () {

  var private = "A private value";
  
  this.printSomething = function() {
      console.log(private);
  }
})();

singleton.printSomething();
2
répondu Mark 2018-02-16 05:40:47

j'ai eu besoin de plusieurs singletons avec:

  • paresseux initialisation
  • paramètres initiaux

et voilà ce que j'ai trouvé:

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 doivent être ensemble pour que cela fonctionne, donc si vous avez des vides variables, juste passer en []

  • j'ai utilisé l'objet window dans la fonction mais j'aurais pu passer dans un paramètre pour créer ma propre portée

  • les paramètres de nom et de construction ne sont que des chaînes de caractères pour que window[] fonctionne, mais avec une simple vérification de type, window.nom et fenêtre.construire sont également possibles.

1
répondu fred 2012-05-29 12:17:55

Qu'est-ce qui ne va pas?

function Klass() {
   var instance = this;
   Klass = function () { return instance; }
}
1
répondu Manav 2012-07-04 02:40:48

de cette façon, assurez-vous que la classe ne peut plus être neuve.

par ceci, vous pouvez utiliser l'op instanceof , aussi, vous pouvez utiliser la chaîne prototype pour hériter de la classe,c'est une classe régulière, mais ne peut pas la nouvelle, si vous voulez obtenir l'instance juste utiliser 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();

si vous ne voulez pas exposer le membre instance , mettez-le simplement dans une conclusion.

1
répondu wener 2013-07-29 12:01:48

ci-dessous est l'extrait de ma promenade à travers pour mettre en œuvre un modèle singleton. Cela m'est venu à l'esprit au cours d'une entrevue et j'ai senti que je devais le saisir quelque part.

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

la même chose peut être trouvé sur mon gist page

1
répondu curioussam 2013-08-23 17:27:23
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
répondu Paul Sweatte 2013-08-23 22:43:52

n'est-ce pas un singleton aussi?

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
répondu Nawal 2015-05-24 13:29:39

vous pouvez le faire avec des décorateurs comme dans cet exemple ci-dessous pour dactylographier:

class YourClass {

    @Singleton static singleton() {}

}

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

alors vous utilisez votre singleton comme ceci:

var myInstance = YourClass.singleton();

au moment d'écrire ces lignes, les décorateurs ne sont pas disponibles dans les moteurs JavaScript. Vous devez vous assurer que votre exécutable JavaScript a réellement activé les décorateurs ou utiliser des compilateurs comme Babel et TypeScript.

notez aussi que l'instance singleton est créée " lazy", c'est à dire, il est créé uniquement lorsque vous l'utilisez pour la première fois.

1
répondu Vad 2016-09-26 11:22:24

motif de Module: "plus lisible". Vous pouvez voir facilement quelles méthodes sont publiques et lesquelles sont privées

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

maintenant vous pouvez utiliser des méthodes publiques comme

Module

.method2(); //-> je suis d'appeler une méthode privée sur une méthode publique alert("salut im une méthode privée")

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

1
répondu ncubica 2016-10-07 16:33:24

Singleton:

Assurer une classe n'a qu'une seule instance et de fournir un point d'accès.

Le Pattern Singleton limite le nombre d'instances d'un objet particulier. Cette instance unique s'appelle le singleton.

  • définit getInstance() qui renvoie l'instance unique.
  • responsable pour la création et la gestion de l'instance de l'objet.

Le Singleton objet est mis en œuvre dans l'immédiat fonction anonyme. La fonction s'exécute immédiatement en l'enveloppant entre parenthèses suivi de deux crochets supplémentaires. On l'appelle anonyme parce qu'il n'a pas de nom.

Exemple De Programme,

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()
1
répondu Mohideen ibn Mohammed 2017-07-18 07:35:32

Voici l'exemple simple pour expliquer le modèle singleton en script java.

 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();
1
répondu Sheo Dayal Singh 2017-09-24 17:20:53

j'aime utiliser une combinaison du Singleton avec le motif du module, ramification en temps init avec un contrôle global NS, enveloppé dans une fermeture. Dans un cas où l'environnement ne va pas changer après l'initialisation du singleton; l'utilisation d'un objet-littéral immédiatement invoqué pour retourner un module plein d'utilités qui persistera pendant une certaine durée devrait être très bien. Je ne passe aucune dépendance, j'invoque juste les singleton dans leur petit monde - le seul but être à: créer un module utilitaire pour lier / délier les événements (les changements d'orientation du périphérique pourraient aussi fonctionner dans ce cas).

window.onload = ( function( _w ) {
            console.log.apply( console, ['it', 'is', 'on'] );
            ( {
                globalNS : function() {
                    var nameSpaces = ["utils", "eventUtils"],
                        nsLength = nameSpaces.length,
                        possibleNS = null;

                    outerLoop:
                    for ( var i = 0; i < nsLength; i++ ) {
                        if ( !window[nameSpaces[i]] ) {
                            window[nameSpaces[i]] = this.utils;
                            break outerLoop;
                        };
                    };
                },
                utils : {
                    addListener : null,
                    removeListener : null
                },
                listenerTypes : {
                    addEvent : function( el, type, fn ) {
                        el.addEventListener( type, fn, false );
                    },
                    removeEvent : function( el, type, fn ) {
                        el.removeEventListener( type, fn, false );
                    },
                    attachEvent : function( el, type, fn ) {
                        el.attachEvent( 'on'+type, fn );
                    },
                    detatchEvent : function( el, type, fn ) {
                        el.detachEvent( 'on'+type, fn );
                    }
                },
                buildUtils : function() {
                    if ( typeof window.addEventListener === 'function' ) {
                        this.utils.addListener = this.listenerTypes.addEvent;
                        this.utils.removeListener = this.listenerTypes.removeEvent;
                    } else {
                        this.utils.attachEvent = this.listenerTypes.attachEvent;
                        this.utils.removeListener = this.listenerTypes.detatchEvent;
                    };
                    this.globalNS();
                },
                init : function() {
                    this.buildUtils();
                }
            } ).init();
        }( window ) );
0
répondu WHill 2013-12-23 18:57:55

vous n'avez pas dit"dans le navigateur". Sinon, vous pouvez utiliser modules NodeJS . Ces sont les mêmes pour chaque require appel . Exemple de base:

Le contenu de toto.js:

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

le contenu du cercle.js:

const PI = Math.PI;

exports.area = (r) => PI * r * r;

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

notez que vous ne pouvez pas accéder à circle.PI , car il n'est pas exporté.

alors que cela ne fonctionne pas dans le navigateur, il est simple et propre.

0
répondu serv-inc 2016-06-22 21:09:16

la clé principale est de comprendre l'importance de la fermeture derrière cela.Ainsi la propriété même à l'intérieur de la fonction intérieure sera privée avec l'aide de la fermeture.

var Singleton = fonction () { 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
répondu Siddhartha 2017-04-06 19:14:14

Singleton en javascript est obtenu en utilisant le modèle de Module et les fermetures. Ci-dessous, le code qui est assez explicite -

// 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
répondu user2756335 2017-04-23 13:11:59

je crois que c'est la manière la plus simple/propre et la plus intuitive bien qu'elle nécessite ES7:

export default class Singleton {

  static instance;

  constructor(){
    if(instance){
      return instance;
    }

    this.state = "duke";
    this.instance = this;
  }

}

le code source est de: adam-bien.com

0
répondu Alt Eisen 2017-08-25 03:50:13