Le mode unique en tant que modèle de développement logiciel a été largement utilisé dans de nombreux langages orientés objet. En JavaScript, le mode unique est également très largement utilisé. Cependant, parce que le langage JavaScript a son approche orientée objet unique, il conduit à. Bien que l'idée du mode unique soit cohérente avec certains langages orientés objet traditionnels, il existe encore des différences dans la mise en œuvre.
Tout d'abord, examinons la définition du modèle singleton dans les langages orientés objet traditionnels : le modèle Singleton est une classe qui ne peut être instanciée qu'une seule fois et accessible via un point d'accès bien connu. Il y a deux points dans cette définition qui mettent en évidence les caractéristiques des langages orientés objet traditionnels, à savoir les classes et les instanciations. Par conséquent, pour les langages orientés objet traditionnels, le mode singleton est basé sur les caractéristiques naturelles de ses classes et instanciations, c'est-à-dire. using key Le mot class définit une classe, qui peut être instanciée via le mot-clé new, mais il faut s'assurer que la même instance est obtenue à chaque fois qu'elle est instanciée par new, ou que son constructeur ne peut être appelé qu'une seule fois via new.
Jetons un coup d'œil à la définition du mode singleton en JavaScript : un singleton est un objet utilisé pour diviser l'espace de noms et organiser ensemble un groupe de méthodes et de propriétés associées. S'il peut être instancié, il ne peut être instancié que par fusion. une fois. En comparant la définition ci-dessus, vous constaterez que la définition unique ici le définit essentiellement comme un objet plutôt que comme une classe dans un langage orienté objet traditionnel. Cela montre également que le langage JavaScript est basé sur des objets. Dans le même temps, il a été souligné plus tard que s'il peut être instancié, cela montre qu'il devrait y avoir plusieurs façons de définir un seul objet en JavaScript. Il existe une ou plusieurs façons de créer un seul objet en utilisant le nouveau mot-clé. Cependant, cette méthode n'est pas une fonctionnalité naturelle de JavaScript lui-même, car les objets créés à l'aide du mot-clé new utilisent en fait une fonction pour simuler la définition de son constructeur (bien qu'ES6 ait commencé à prendre en charge le mot-clé class, il n'a pas encore été visualisé (largement pris en charge par tous les navigateurs)), alors comment utiliser les fonctionnalités naturelles de JavaScript pour implémenter le mode singleton ?
var Singleton={ attribute1:true, attribute2:10, method1:function(){ }, method2:function(arg){ } }
Un objet Singleton est défini ici, qui contient plusieurs propriétés et méthodes. Il est inclus dans la page. Cet objet est créé lors du chargement de js, utilisez Singleton.method1 pour l'appeler comme la page. est chargé et le processus d'analyse et d'exécution de js est terminé, nous n'utilisons pas le new mot-clé pour instancier cet objet. C'est également une grande différence entre l'implémentation du mode unique en JavaScript et les langages orientés objet traditionnels. Cette méthode est plus simple et plus facile à comprendre. Cependant, cette méthode présente plusieurs inconvénients. Un inconvénient évident est qu'elle ne fournit pas d'espace de noms. Si d'autres programmeurs définissent également une variable Singleton dans la page, il est facile de réécrire et de confondre l'objet unique, donc pour résoudre ce problème, réécrivez. comme suit :
var mySpace={}; mySpace.Singleton={ attribute1:true, attribute2:10, method1:function(){ }, method2:function(arg){ } }
Ici, nous définissons d'abord un espace de noms mySpace, puis montons l'objet Singleton sous cet objet. Cela réduit considérablement la possibilité de conflits et de mauvaises opérations avec d'autres programmeurs, même si d'autres sont dans la portée globale. La définition d'une variable Singleton ne polluera pas. l'objet unique. Cela permet de diviser l'espace de noms et d'organiser ensemble certaines propriétés et méthodes associées, comme mentionné dans la définition précédente.
Cette méthode présente encore des défauts. Toutes les propriétés et méthodes de cet objet unique sont communes et peuvent être consultées et modifiées par l'extérieur à tout moment. Par conséquent, les fermetures sont utilisées pour simuler des propriétés et des méthodes privées, comme suit :
mySpace.Singleton=(function(){ var privateAttribute1=false; var privateAttribute1=[1,2,3]; function privateMethod1(){ } function privateMethod2(){ } return { publicAttribute1:true, publicAttribute2:10, publicMethod1:function(){ privateAttribute1=true; privateMethod1(); }, publicMethod2:function(arg){ privateAttribute1=[4,5,6]; privateMethod2(); } } })();
Ici, nous attribuons directement une fonction anonyme auto-exécutable à l'objet unique. Dans cette fonction, nous utilisons les mots-clés var et function pour définir respectivement ses propriétés et méthodes privées. Celles-ci ne sont pas directement accessibles en dehors de la fonction (en dehors de l'objet unique). Accessible, car dès que la fonction est exécutée, l'espace dans sa portée interne sera récupéré, c'est pourquoi les fermetures peuvent être utilisées pour simuler des propriétés et des méthodes privées. Dans cette fonction (fermeture), un objet est finalement renvoyé. Cet objet contient des méthodes et propriétés publiques, qui peuvent être appelées directement de l'extérieur, car ces méthodes publiques sont définies à l'intérieur de la fonction, leurs propriétés privées et. Les méthodes peuvent être appelées.Cependant, le monde extérieur ne peut effectuer que certaines opérations via les méthodes et propriétés publiques renvoyées, et ne peut pas appeler directement les propriétés Singleton.privateMethod1. Cela permet à l'objet unique non seulement d'empêcher le monde extérieur d'accéder directement à ses propriétés et méthodes privées, mais également de fournir des propriétés et méthodes communes au monde extérieur pour effectuer certaines opérations.
Ce mode singleton construit par auto-exécution de fonction anonyme est largement utilisé dans de nombreuses bibliothèques js, mais il y a toujours un problème si nous n'avons pas besoin d'utiliser l'objet lors du chargement de la page, et l'objet quand cela coûte cher. créer (par exemple nécessiter de nombreux calculs ou des accès multiples à l'arborescence DOM et à ses propriétés, etc.), une approche raisonnable consiste à le créer lorsque vous en avez besoin, plutôt que de le créer directement avec l'analyse et l'exécution de js. Ce concept est appelé chargement différé, le code ci-dessus est donc modifié comme suit :
mySpace.Singleton=(function(){ var uniqueInstance; function constructor(){ var privateAttribute1=false; var privateAttribute1=[1,2,3]; function privateMethod1(){ } function privateMethod2(){ } return { publicAttribute1:true, publicAttribute2:10, publicMethod1:function(){ privateAttribute1=true; privateMethod1(); }, publicMethod2:function(arg){ privateAttribute1=[4,5,6]; privateMethod2(); } } } return { getInstance:function(){ if(!uniqueInstance){ uniqueInstance=constructor(); } return uniqueInstance; } } })();
Ici, nous définissons d'abord une variable privée uniqueInstance dans la fonction anonyme comme handle pour déterminer si l'objet unique a été créé, puis mettons toutes les propriétés et méthodes que nous venons de définir pour l'objet unique dans un constructeur dans la fonction, l'objet unique ne sera créé que lorsque la fonction est appelée, sinon il ne sera pas créé directement. Ensuite, un objet est renvoyé, qui contient une méthode getInstance. Cette méthode est destinée aux appels externes, déterminez d'abord si l'objet unique existe, renvoyez-le directement. Sinon, appelez la fonction constructeur pour construire le. un seul objet. Revenez-y à nouveau. Enfin, si nous appelons une méthode de l'objet unique, nous devons utiliser mySpace.Singleton.getInstance().publicMethod1() Ici, l'objet unique ne sera créé que lorsque nous l'appellerons ainsi, sinon l'objet unique ne le sera pas. être créé sera automatiquement créé, ce qui implémente en fait le chargement à la demande ou le chargement paresseux.