Como modelo de desarrollo de software, el patrón monolítico se ha utilizado ampliamente en muchos idiomas orientados a objetos. En JavaScript, el patrón monolítico también se usa ampliamente. Sin embargo, debido a que el lenguaje JavaScript tiene su método único orientado a objetos, es consistente con algunos idiomas tradicionales orientados a objetos, pero sigue siendo diferente en la implementación.
Primero, echemos un vistazo a la definición de patrones de monómero en idiomas tradicionales orientados a objetos: los patrones de monómero son clases que solo se pueden instanciar una vez y se puede acceder a través de un punto de acceso conocido. Hay dos puntos en esta definición que resaltan las características de los idiomas tradicionales orientados a objetos, a saber, clase e instanciación. Por lo tanto, para los idiomas tradicionales orientados a objetos, el patrón monolítico se basa en las características naturales de su clase e instanciación. Es decir, use la clase de palabras clave para definir una clase, que se puede instanciar a través de la nueva palabra clave, pero debe asegurarse de que cada vez que se instancia por nueva, se obtiene la misma instancia o que su constructor solo puede llamarse una vez a través de NUEVO.
Echemos un vistazo a la definición del patrón de monómero en JavaScript: Monomer es un objeto utilizado para dividir el espacio de nombres y organizar un lote de métodos y atributos relacionados juntos. Si se puede instanciar, solo se puede instanciar una vez. Comparando la definición anterior, encontrará que la definición de monómero aquí define su esencia como un objeto, en lugar de una clase en un lenguaje tradicional orientado a objetos, que también muestra que el lenguaje de JavaScript está basado en objetos. Al mismo tiempo, se señaló más tarde que si se puede instanciar, esto muestra que debería haber varias formas de definir monómeros en Javascript. Hay una o más formas de instanciar que se pueden instanciar, es decir, usar la nueva palabra clave para crear objetos de monómero. Sin embargo, este método no es una característica natural del propio JavaScript, porque los objetos creados con la nueva palabra clave en realidad son simuladas y definidas a través de funciones (aunque ES6 ha comenzado a admitir la palabra clave de clase, el navegador aún no lo ha compatible). Entonces, ¿cómo usar las características naturales de JavaScript para implementar patrones de monómero?
var singleton = {attribute1: true, attribute2: 10, método1: function () {}, método2: function (arg) {}}Aquí hay un objeto Singleton, que contiene varias propiedades y métodos. Está incluido en la página. Este objeto se crea cuando JS está cargado. Se llama usar singleton.method1 al llamar. Su instanciación se completa durante la ejecución de la página de carga JS. No usamos la nueva palabra clave para instanciar este objeto. Esta también es una gran diferencia entre la implementación de patrones monolíticos en JavaScript y los idiomas tradicionales orientados a objetos. Este método es más simple y fácil de entender. Sin embargo, este método tiene varias desventajas. Una desventaja obvia es que no proporciona un espacio de nombres. Si otros programadores también definen una variable singleton en la página, es fácil sobrescribir y confundir el objeto monolítico. Entonces, para este problema, se reescribe de la siguiente manera:
var myspace = {}; myspace.singleton = {attribute1: true, attribute2: 10, método1: function () {}, método2: function (arg) {}}Aquí, un espacio de nombres de MySpace se define primero, y luego el único objeto Singleton se monta debajo de este objeto, lo que reduce en gran medida la posibilidad de conflictos con otros programadores y la incompletra. Incluso si otros definen una variable singleton en el alcance global, no contaminará el objeto Singleton. Esto implementa la función de dividir el espacio de nombres y organizar algunos atributos y métodos relacionados como se menciona en la definición anterior.
Este método todavía tiene sus desventajas. Todas las propiedades y métodos de este objeto monolítico se comparten y se puede acceder y modificar en cualquier momento desde el exterior. Por lo tanto, los cierres se utilizan para simular propiedades y métodos privados, de la siguiente manera:
myspace.singleton = (function () {var privateAtTribute1 = false; var privateAtTribute1 = [1,2,3]; function privateMethod1 () {} function privateMethod2 () {} return {publicTribute1: true, publicAttribute2: 10, publicMethod1: function () {privateattribute1 = true; publicMethod2: function (arg) {privateAtTribute1 = [4,5,6];Aquí asignamos directamente una función anónima de auto-ejecutación al objeto Monolito. En esta función, las palabras clave VAR y la función se utilizan para definir sus propiedades y métodos privados respectivamente. No se puede acceder directamente a estos fuera de la función (fuera del objeto Monolito), porque una vez que se ejecuta la función, el espacio de su alcance interno se reciclará, por lo que los cierres se pueden usar para simular propiedades y métodos privados. En esta función (cierre), finalmente se devuelve un objeto, que contiene algunos métodos y propiedades públicas, que pueden llamarse directamente afuera. Al mismo tiempo, dado que estos métodos públicos se definen dentro de la función, pueden llamar a sus propiedades y métodos privados. Sin embargo, el mundo exterior solo puede completar ciertas operaciones a través de los métodos y propiedades públicos devueltos, y no puede llamar directamente propiedades como Singleton.PrivateMethod1. Esto hace que el objeto monolítico no solo aislara el mundo exterior para acceder directamente a sus propiedades y métodos privados, sino que también proporciona algunas propiedades y métodos comunes al mundo exterior para completar ciertas operaciones.
Este patrón monolítico construido por la autoexecución de las funciones anónimas se usa ampliamente en muchas bibliotecas JS, pero todavía hay un problema. Si no necesitamos usar el objeto al cargar la página, y la creación del objeto es más costosa (como muchos cálculos o acceso múltiple al árbol DOM y sus propiedades, etc.), es razonable crearlo cuando sea necesario, en lugar de crearlo directamente con el análisis y la ejecución de JS. Este concepto se llama carga perezosa, así que modifique el código anterior de la siguiente manera:
myspace.singleton = (function () {var uniqueinstance; functive constructor () {var privateTtribute1 = false; var privateTtribute1 = [1,2,3]; function privateMethod1 () {} function privateMethod2 () {} return {publictribute1: true, publicAttribute2: 10, publicMethod1: Function () {) privateTrute1 = true;Aquí, una variable privada única se define en la función anónima como un mango para determinar si se ha creado un objeto monolítico. Luego, todos los atributos y métodos definidos para el objeto monolítico se han colocado en una función llamada constructor. Solo cuando se llama la función se puede crear el objeto monolítico, de lo contrario no se creará directamente. Luego, devuelva un objeto, que contiene un método GetInstance, que es para llamadas externas. Al llamar al método, primero determine si existe el objeto monolítico. Si existe, devuélvelo directamente. De lo contrario, llame a la función del constructor para construir el objeto monolítico y devuélvalo. Finalmente, si llamamos un método del objeto monolítico, necesitamos usar myspace.singleton.getInstance (). PublicMethod1 (). Aquí, solo crearemos este objeto monolítico cuando llamemos de esta manera, de lo contrario, el objeto monolítico no se creará automáticamente, lo que realmente implementa la carga a pedido o la carga perezosa.