Estoy haciendo mi primer proyecto de JavaScript que hace un uso intensivo de los objetos. Debido a cómo funciona, casi todos los objetos personalizados se hacen así:

namespaceobj = {};
namespaceobj.subobject = {};
namespaceobj.subobject.somefunction = function(arg, uments) {
    // Do Stuff
}
namespaceobj.subobject.somedata = 10;
namespaceobj.othersubject = {};
namespaceobj.othersubject.somefunction = function(some, args) {
    // Do more stuff
}
// More subobjects etc.

Lo cual está bien, ya que todos los objetos personalizados solo tienen una sola instancia de todos modos (ejemplos de subobjetos son la interfaz de usuario, las herramientas, los datos compartidos, etc.).

Sin embargo, he visto que el código hizo algo como esto (la sintaxis probablemente sea incorrecta, esto es solo por la memoria de ver un código similar)

function SomeClass() {
    this.somedata = 42;
    this.somefunction = function(a, few, args) {
        // Do Stuff
    }
}
// More classes and stuff
// Elsewhere:
someInstance = new SomeClass(); // AFA I recall, new was optional
someInstance.somefunction();

¿Podría alguien explicar cómo funcionan las "clases" en el segundo ejemplo, y cualquier dificultad que pueda encontrar al usarlas?

3
Macha 17 may. 2009 a las 16:53

4 respuestas

La mejor respuesta

Creo que la sintaxis en la que estabas pensando se ve así:

function SomeClass() {
    var somedata = 42;
    this.somefunction = function(a, few, args) {
    // Do Stuff like:-
    return somedata + a;
  }
}
// More classes and stuff
// Elsewhere:
someInstance = new SomeClass(); // AFA I recall, new was optional
someInstance.somefunction(15);  //returns 57

La función que se asigna a alguna función se crea en un Contexto de ejecución que se produce cuando se ejecuta una función (en este caso, cuando SomeClass () se ejecuta como parte de la nueva operación que se asigna a someInstance) . Las funciones pueden acceder a las variables que forman parte del contexto de ejecución en el que se crean, por lo que en este caso, algunos datos son una variable a la que algunas funciones tienen acceso.

Este enfoque efectivamente hace que algunos datos sean el estado privado del objeto, ya que solo las funciones creadas dentro del cuerpo de la función SomeClass pueden acceder a él.

Esta es una simplificación excesiva, primero debe considerar investigar Javascript sin referencia a la programación OO, aprender sobre cadenas de alcance y cadenas de prototipos . Cuando comprende esto, puede comprender mejor la cantidad de enfoques diferentes para implementar un diseño OO en Javascript y cuál enfoque se adapta mejor a sus necesidades.

2
AnthonyWJones 17 may. 2009 a las 13:44

Este es un tema bastante importante, pero lo que está viendo es la diferencia entre notación literal de objeto (su primer ejemplo) y la marca particular de OOP de JavaScript. La principal diferencia que encontrará entre los dos es que su primer ejemplo tiene solo una instancia estática, mientras que una versión revisada de su segundo ejemplo (estaba cerca) le permitiría crear múltiples instancias de la clase.

Le sugiero que lea JavaScript y programación orientada a objetos (OOP):

JavaScript es un excelente lenguaje para escribir aplicaciones web orientadas a objetos. Puede admitir OOP porque admite la herencia a través de la creación de prototipos, así como las propiedades y métodos. Muchos desarrolladores descartan JS como un lenguaje OOP adecuado porque están muy acostumbrados al estilo de clase de C # y Java. Muchas personas no se dan cuenta de que JavaScript admite la herencia. Cuando escribes código orientado a objetos, instantáneamente te da poder; puede escribir código que pueda reutilizarse y que esté encapsulado.

2
Andrew Hare 17 may. 2009 a las 12:58

La segunda forma es quizás la mejor forma porque crea una "Clase" que tiene numerosas funciones viviendo en su prototipo. Cuando se crea una nueva Clase, la nueva instancia también obtiene su prototipo configurado de la misma manera. En el ejemplo de Class, las funciones viven en el prototipo.

Los primeros ejemplos simplemente crean un objeto con muchas funciones reasignando las mismas funciones a cada objeto cada vez que sea necesario.

Los prototipos son preferibles porque significa que el trabajo de definir la "clase" solo se realiza una vez. Todas las instancias comparten el mismo prototipo, por lo tanto, uno puede lograr construcciones poderosas como agregar / cambiar / eliminar funciones y todas las instancias verán el cambio. En el primer ejemplo que da, todos son objetos independientes donde uno puede cambiar cualquier cosa en cualquier instancia de forma independiente.

Al final, todos los objetos Javascript son tablas hash de propiedades y funciones. Cuando uno accede a un objeto a través de "object.something", todo es un valor, incluidas las funciones. Sin embargo, cuando se usa la notación de invocación de función "object.foo (...)", el tiempo de ejecución intenta encontrar un "foo" en "objeto". Si el tiempo de ejecución no puede encontrar un "foo" en "objeto", entonces intentará encontrar un "foo" en el prototipo de "objeto". Esto continúa hasta que se encuentra algo o no quedan más prototipos.

El tiempo de ejecución intentará invocar parámetros de paso "foo", etc. Naturalmente, las cosas explotarán si foo no es una función.

0
Benjamin 7 jul. 2014 a las 10:50

El segundo ejemplo es más claro y los datos están encapsulados. Significa que algunas variables de clase se pueden calcular usando las temporales. También los segundos ejemplos son mejores para hacer más objetos del mismo tipo, pero en su caso no es importante. De todos modos, no ralentizará su código, por lo que puede hacerlo como desee.

0
Thinker 17 may. 2009 a las 12:56