¿Cómo construir una "clase" (con propiedades y métodos) sobre la cual se crearán muchas instancias?¿Cuál es la forma moderna de estructurar una "clase" en JavaScript?
Respuesta
Here is a basic class with explanation on how to create them.
Para forma moderna, todas las tuercas y tornillos será el mismo. Nada de lujos al respecto :)
JavaScript no utiliza clases de la misma manera que Java, C++ o similares.
Una forma de lograr su efecto es definir una función en la que se use la palabra clave , accediendo a los miembros más o menos como lo haría en Java. A continuación, utilice la nueva palabra clave al llamar a esta función para crear un objeto.
function Foo(){ //vaguely like a Java constructor
this.aField = 1; //define members simply by using 'this'
this.aMethod = methodFunction; //assign a function as a member using 'this'
}
function methodFunction(){
}
var foo = new Foo(); //construct an object
El enfoque de la orientación a objetos más nativa de JavaScript es utilizar herencia de prototipos, pero existen muchos otros patrones, incluyendo la herencia pseudoclassical, que imita el patrón de herencia basado en clases en lenguajes como C y Java. Douglas Crockford ha escrito y hablado sobre el tema y ofrece algunas muy buenas explicaciones de cada uno. Echar un vistazo a los siguientes artículos:
// I like this pattern..
// class
function Person(name, birthdate) {
this._name = name;
this._birthdate = birthdate;
/* should not do this
* this.getAge = function() {
* }
* as the method will be constructed
* for each instance, better to let it
* be inherited from prototype, see below
*/
}
// class methods
Person.prototype.getBirthdate = function() {
return this._birthdate;
}
// same as above, function as a method
Person.prototype.getAge = function() {
var currentDate = new Date();
// age in millis
return currentDate - this._birthdate;
}
// the get age method can be a "static"
// method on the constructor function if you pass the
// person object
Person.getAge = function(person) {
var currentDate = new Date();
// age in millis
//no reference to this
return currentDate - person.getBirthdate();
}
// you could use it like this
myPerson = new Person("Steve", new Date("1980-01-01"));
// returns age in millis
myPerson.getAge();
// returns age in millis
Person.getAge(myPerson);
También podría utilizar una función anónima para simular privada y pública
var PersonFactory = (function() {
// private area, no one can alter
// the person cache
var _cache = {}
// public area
return {
// returns a person born now
getPerson: function(name) {
if(_cache[name]) {
return _cache[name];
}
else {
_cache[name] = new Person(name, new Date());
return _cache[name];
}
}
}
})();
var p = PersonFactory.getPerson("Leif");
p.getAge();
p = PersonFactory.getPerson("Leif");
// should be the same age/obj
p.getAge();
No me gusta este patrón aunque. La advertencia de subrayado _myVariable debería ser suficiente para evitar que los usuarios de tu lib utilicen esas variables/métodos. Lo usé asignado cuando lo descubrí por primera vez debido a mi fondo de Java ... Hace que sea difícil trabajar con herencia de prototipos y puede causar pérdidas de memoria.
En JavaScript "moderno", hay tres métodos populares para definir objetos.
El primer método es el método clásico y sigue siendo popular debido a su simplicidad; sin embargo, es discouraged by MDC a favor del segundo método debido a la ineficiencia de tener que redefinir cada función cada vez que se crea una instancia del objeto.
// Constructor, methods and members all rolled up into one definition
var Movie = function(name) {
this.name = name;
// Note that private members can be created using the closure property
var _id = +(new Date());
this.getName = function() {
return this.name + " " + _id;
};
this.setName = function(name) {
this.name = name;
};
};
var m = new Movie("Beerfest");
El segundo método es una variación de y se puede usar indistintamente con el primero. También es útil para agregar nuevos métodos a objetos existentes a través de la propiedad prototype
. Los miembros privados y los métodos no son posibles en esta forma.
// Constructor is separate from its methods
var Movie = function(name) {
this.name = name;
}
Movie.prototype.getName = function() {
return name;
};
Movie.prototype.setName = function(name) {
this.name = name;
};
var m = new Movie("Kill Bill");
El tercer método es utilizar el module pattern, lo que hace posible instanciar objetos sin tener que utilizar el operador new
.
var Movie = function (name) {
var _id = +(new Date());
var privateMethod = function() { alert(_id); };
// All methods and members defined here are public
return {
name: name,
getName: function() {
return this.name + " " + _id;
},
setName: function(name) {
this.name = name;
}
};
};
var m = Movie("Stackoverflow: the movie");
Tenga en cuenta que en los métodos primero y tercero, puede utilizar miembros y métodos de acceso privado. Pero tenga en cuenta que to use this
within private methods some must happen.
Al utilizar una función autoejecutable anónima, puede permitir atributos/métodos públicos y privados.
Este es el modelo que más me gusta:
(function ($, MyObject, undefined) {
MyObject.publicFunction = function() {
console.log("Public function");
};
var privateFunction = function() {
console.log("Private function");
};
var privateNumber = 0;
MyObject.sayStuff = function() {
this.publicFunction();
privateFunction();
privateNumber++;
console.log(privateNumber);
};
// You can even nest the namespaces
MyObject.nestedNamespace = MyObject.nestedNamespace || {};
MyObject.nestedNamespace.logNestedMessage = function() {
console.log("Nested namespace function");
};
}(jQuery, window.MyObject = window.MyObject || {}));
MyObject.sayStuff();
MyObject.sayStuff();
MyObject.nestedNamespace.logNestedMessage();
MyObject.publicFunction();
se enterara por los comentarios here y this article.
- 1. Cuál es la forma correcta para extender un método de la clase padre en Python moderna
- 2. ¿La forma moderna de borrar contenido flotante?
- 3. ¿Cuál es la mejor forma de diseñar una clase C#?
- 4. ¿Cuál es la forma preferida de estructurar y construir proyectos OCaml?
- 5. ¿Cuál es la forma más moderna de iniciar sesión en syslog con un manejador java.util.logging?
- 6. ¿Cuál es la forma correcta de crear una clase de Javascript?
- 7. ¿Cuál es la forma más actual de estructurar la navegación Breadcrumb utilizando HTML5
- 8. ¿Cuál es la forma moderna de crear un módulo XS desde cero?
- 9. ¿Cuál es la forma más rápida de saltar a un constructor (es) en una clase?
- 10. ¿Cuál es una buena forma de estructurar una tabla de registros de 100M para consultas rápidas ad-hoc?
- 11. ¿Es esta una forma segura de estructurar una mysql_query en PHP
- 12. ¿Cuál es la forma más confiable de verificar si una variable de JavaScript es nula?
- 13. ¿Cuál es la forma 'moderna' de encontrar elementos comunes en dos listas <T> de objetos?
- 14. ¿Cuál es la forma correcta de usar un registrador en una clase Serializable de Java?
- 15. ¿Cuál es la forma más simple de disminuir una fecha en Javascript en 1 día?
- 16. ¿Cuál es la mejor forma de insertar configuraciones en Javascript en una aplicación MVC?
- 17. ¿Cuál es la forma idiomática de realizar una conversión/tipo de letra "entero" en javascript?
- 18. ¿Cuál es la forma más corta de implementar una clase proxy o decorador en C#?
- 19. ¿Cuál es la forma correcta de implementar la comparación para una clase base?
- 20. ¿Cuál es la forma más limpia de escribir una cadena multilínea en JavaScript?
- 21. ¿Cuál es una buena forma de ejecutar Javascript de forma interactiva?
- 22. Android Eclipse: ¿Cuál es la forma más fácil de duplicar una clase?
- 23. ¿Cuál es la forma correcta de especificar una clase principal al empaquetar un contenedor utilizando m2eclipse?
- 24. ¿Cuál es la forma más fácil de probar la membresía de clase en coffeescript?
- 25. ¿Cuál es la forma estándar de agregar documentación a una función de JavaScript?
- 26. ¿Cuál es la forma más simple de ejecutar una clase Java cada 30 segundos?
- 27. ¿Cuál es la forma más común de decir "no javascript" en el encabezado de la solicitud?
- 28. ¿Cuál es la forma correcta de verificar la igualdad de cadenas en JavaScript?
- 29. Javascript ¿cuál es la propiedad en hasOwnProperty?
- 30. ¿Cómo estructurar mi código javascript/jquery?
corrigió la asignación del método; Espero que no te importe ... – Christoph
A menos que uses 'methodFunction' en más de una clase, definirlo fuera de' f' no tiene ningún propósito real excepto contaminar el alcance global. –
@Justin: definir 'methodFunction()' fuera del constructor definitivamente sirve para un propósito real: de lo contrario, se debe crear un nuevo objeto de función para cada instancia (es decir, una sobrecarga 'O (N)' en el número de 'f' objetos); normalmente, asignaría el método a 'f.prototype', pero hacerlo ralentizaría ligeramente la búsqueda de métodos – Christoph