insertar - ¿Cómo configurar el espacio de nombres y las clases de JavaScript correctamente?
insertar codigo java en html (5)
Parece que hay muchas maneras de configurar una aplicación JavaScript, por lo que es confuso saber cuál es la correcta o la mejor. ¿Hay alguna diferencia con las técnicas siguientes o una mejor manera de hacerlo?
MyNamespace.MyClass = {
someProperty: 5,
anotherProperty: false,
init: function () {
//do initialization
},
someFunction: function () {
//do something
}
};
$(function () {
MyNamespace.MyClass.init();
});
De otra manera:
MyNamespace.MyClass = (function () {
var someProperty = 5;
var anotherProperty = false;
var init = function () {
//do something
};
var someFunction = function () {
//do something
};
return {
someProperty: someProperty
anotherProperty: anotherProperty
init: init
someFunction: someFunction
};
}());
MyNamespace.MyClass.init();
La primera técnica se siente más como una clase. Vengo del fondo del lado del servidor si esto hace la diferencia. La segunda técnica parece más redundante y un poco incómoda, pero veo que esto también se usa mucho. ¿Alguien puede por favor ayudar a arrojar algo de luz y aconsejar la mejor manera de seguir adelante? Quiero crear una aplicación con muchas clases hablando entre sí.
El primer ejemplo es simplemente un literal Objeto : no se puede crear una instancia y no tiene miembros privados. El segundo ejemplo tiene una sintaxis incorrecta ( var someProperty: 5
debe ser var someProperty = 5
) pero está usando un cierre para encapsular el estado interno interno dentro de una función anónima de invocación automática.
El segundo enfoque se ve mejor para encapsular miembros privados, pero podría hacerse más "orientado a objetos" al convertirlo en una clase instanciable:
MyNamespace.MyClass = function() { ... };
MyNamespace.MyClass.prototype.someProperty = ''foo'';
Luego puede instanciarlo con la palabra clave ''nueva'':
var aClass = new MyNamespace.MyClass();
aClass.init(...);
No hagas ninguna de esas cosas.
Haz una "clase" de javascript:
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass();
Uno con vars estáticos:
var MyClass = (function(){
var static_var; //static private var
var MyClass = function () {
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
return MyClass;
})();
MyNamespace.MyClass = new MyClass();
Con un "constructor" (todos los ejemplos tienen un "constructor", este solo tiene parámetros para trabajar):
var MyClass = function (a, b c) {
//DO SOMETHING WITH a, b, c <--
var privateVar; //private
var privateFn = function(){}; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
MyNamespace.MyClass = new MyClass(1, 3, 4);
Con todo lo anterior, puede hacer :
MyNamespace.MyClass.someFunction();
Pero no puedes hacer (desde el exterior):
MyNamespace.MyClass.privateFn(); //ERROR!
Uso la siguiente sintaxis para las clases instanciables con espacio de nombres
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
Por qué nunca deberías usar
return { methodName : methodDelegate}
como en el segundo ejemplo:
MyNamespace.MyClass = (function () {
var someProperty = 5;
var init = function () {
//do something
};
return {
someProperty: someProperty
someFunction: someFunction
};
}());
MyNamespace.MyClass.init();
Cuando usa el espacio de nombres, debe pensar en él como en una declaración, no en la instancia.
MyNamespace = {};
MyNamespace.sub = {};
MyNamespace.anotherSub = {};
MyNamespace.sub.MyClass = (function () {
var static_var; //static private var
var MyClass2 = function () {
var privateVar; //private
var privateFn = function () { }; //private
this.someProperty = 5; //public
this.anotherProperty = false; //public
this.someFunction = function () { //public
//do something
};
};
return MyClass2;
})();
debugger;
var c1 = new MyNamespace.sub.MyClass();
c1.someProperty = 1; // creates 5->1.
var c2 = new MyNamespace.sub.MyClass();
c2.someProperty = 2; // creates 5->2. c1 is still 1
debugger;
var myClass = function () {
var someProperty = 5;
var anotherProperty = false;
var init = function () {
//do something
};
var someFunction = function () {
//do something
};
return {
someProperty: someProperty,
anotherProperty: anotherProperty,
init: init,
someFunction: someFunction
};
};
MyNamespace.MyClass = myClass();
var c2 = MyNamespace.MyClass;
// how are planning to create one more object, while it''s a reference? copy //the whole one?
c2.someProperty = 2; // changes 5 -> 2
var c3 = MyNamespace.MyClass.init(); // create 2 instead of 5
c3.someProperty = 3; // changes c3 and c3 from 2 to 3.
console.log(c2.someProperty + c3.someProperty);
Y no importa cuánto se popularizó el módulo antipatrón. La declaración le brinda la capacidad de utilizar el mismo código con diferentes instancias de una manera esperada para otros desarrolladores. La calidad del código y la simplicidad de su lectura aumentan. El objetivo de cualquier desarrollador es escribir un código simple para leer, no más corto o SECO, pero fácil de leer y ser entendido por otro desarrollador. Eso disminuye la cantidad de errores primero. (c) S. McConnell
Cómo combinar espacio de nombres y declaración de clase:
var ns = { // your namespace
my_value: 1, // a value inside the namespace to avoid polluting
MyClass: function() { // a class inside the namespace
this.class_property: 12,
this.class_method: function() {
console.log("My property: " + this.class_property);
}
},
myFunction: function() { // a function inside a namespace
console.log("I can access namepsace value if you don''t use ''new'': " + this.my_value);
}
};
Accediendo a tu valor:
console.log(ns.my_value);
Ahora, para la clase y la función: si usa new
, la palabra this
dentro de la función apuntará a su constructor. Si no usa new
, this
apuntará al espacio de nombre. Asi que,
Usando una clase:
var obj = new ns.MyClass();
Usando la función:
ns.myFunction();
Si construye el objeto sin new
, this
apuntará al espacio de nombre, por lo que el espacio de nombre se "destruirá" porque se le MyClass.class_property
y MyClass.class_method
.