Estoy tratando de implementar espacios de nombres anidados usando el patrón de módulos con funciones anónimas y cierre. Me falta algo cuando se trata de cambios en las variables de estado. Por ejemplo, aquí hay un conjunto simple de espacios de nombres anidados:
// namespace 1 var first = (function(){ 'use strict'; var v = 1; function method(){ console.log("method 1: " + v); } // namespace 2 var second = (function(){ var v = 2; function method(){ console.log("method 2: " + v); } // namespace 3 var third = (function(){ var v = 3; function method(){ console.log("method 3: " + v); } return { v: v, method: method }; })(); return { third: third, v: v, method: method }; })(); return { second: second, v: v, method: method }; })(); first.method(); first.v = 4; first.method(); first.second.method(); first.second.third.method();Esto da como resultado el siguiente resultado:
"method 1: 1" "method 1: 1" "method 2: 2" "method 3: 3" ¿Por qué no se mantiene el cambio a first.v ?
ACTUALIZACIÓN: Entonces, ahora veo por qué esto no funcionó según los comentarios. Ahora cambié a usar literales de objeto. Todavía estoy tratando de encontrar el mejor enfoque para los espacios de nombres anidados y el alcance. Aquí está mi nueva versión del código anterior:
var first = { v: 1, method: function (){ console.log("method 1: " + this.v); }, second: { v: 2, method: function (){ console.log("method 2: " + this.v); }, third: { v: 3, method: function (){ console.log("method 3: " + this.v); } } } } first.method(); first.v = 4; first.method(); first.second.method(); first.second.third.method();Los espacios de nombres no se crean mediante funciones de anidamiento. Se crean creando nuevas propiedades en un objeto existente y luego adjuntando nuevos miembros a esas propiedades:
(function(){ // Just create members of the instance as normal // No nesting here. Within a function variables are // private, but "this" properties are available // and can persist state. this.foo = function(){console.log("foo"); }; this.bar = function(){console.log("bar")}; this.baz = function(){console.log("baz")}; this.x = 42; // We can't change the state of the above variable directly // but we can create a function that works with that value // and modifies it. this.changeX = function(n){ this.x += n; }; // If we create a new property on the Global object // that is an empty object, we'll be essentially // creating a namespace to be accessed from the Global object window.namespace = {}; // Then, create new properties on that object, which point // to state or behavior that you want to expose in the namespace window.namespace.foo = foo; window.namespace.bar = bar; window.namespace.x = x; window.namespace.changeX = changeX; // And to create nested namespaces, repeat by adding a new empty // object as a new property of the current namespace. window.namespace.ns2 = {}; // And then associate internal state or behavior with that namespace window.namespace.ns2.baz = baz; })(); // Since our namespace is attached to the Global object (window), // we don't have to fully qualify it with window and can just // access the namespace directly. namespace.foo(); namespace.bar(); namespace.ns2.baz(); console.log(namespace.x); // 42 namespace.changeX(-10); console.log(namespace.x); // 32