Pregunta

Sé que hay muchas preguntas similares y toneladas de excelentes respuestas a esto.Intenté observar los métodos de herencia clásicos, o esos métodos de cierre, etc.De alguna manera considero que para mí son más o menos métodos de "pirateo", ya que en realidad no reflejan para qué está diseñado JavaScript.(Bienvenido que cualquiera me corrija si me equivoco).Bien, mientras funcione, cumplo con el patrón de herencia clásico como:

PARENTClass = function (basevar) { do something here; };
PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen 

// Inheritance goes here
CHILDClass = function (childvar) { do something; };
CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
// Instance
CHILDInstance = new CHILDClass(whatever);

Lo anterior es de alguna manera, a mi entender, la herencia de JS.Pero un escenario que no tengo idea de cómo implementar es qué pasa si quiero inicializar DURANTE la creación del objeto (es decir, dentro del constructor) y el nuevo objeto se puede usar de inmediato...Es posible que mi ilustración del problema no sea muy clara, así que permítanme usar el siguiente Psuedo en C# para explicar lo que quiero hacer:

class PARENT {
    public PARENT (basevar) { ... }
}
class CHILD : PARENT {
    public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
    { ... }
}

Por alguna razón (como init.Elementos de la interfaz de usuario), ponerlos en el constructor parece la mejor manera de hacerlo.Alguien tiene idea de cómo puedo hacerlo.

PD:en el *1, no tengo idea de qué debería poner allí.PS2:La situación anterior que encontré que la biblioteca jquery.inherit puede hacer, solo me pregunto si no usar la biblioteca puede lograrlo.PS3:O mi entendimiento es incorrecto.Dado que JavaScript no pretende imitar la programación orientada a objetos (por eso lo llamo hack), ¿cuál es la lógica "CORRECTA" para implementar esto?

¿Fue útil?

Solución

No es un cortar a tajos como tal;JavaScript es un lenguaje prototipo, tal como lo define Wikipedia como donde:

...las clases no están presentes y la reutilización del comportamiento (conocida como herencia en lenguajes basados ​​en clases) se realiza mediante un proceso de clonación de objetos existentes que sirven como prototipos.

Como dice, las clases no se utilizan en JavaScript;Cada objeto que creas desciende de JavaScript. Object;todos los objetos en JavaScript tienen la prototype objeto, y todas las instancias de objetos que usted crea 'heredan' métodos y propiedades del objeto prototipo de su objeto.Échale un vistazo al MDC prototipo referencia de objeto para obtener más información.

A partir de esto, cuando llamas a la línea:

CHILDClass.prototype = new PARENTClass();

Esto permite que el CHILDClass objeto para agregar métodos y propiedades a su objeto prototipo desde el PARENTClass objeto, lo que crea un efecto similar a la idea de herencia presente en los lenguajes basados ​​en clases.desde el prototype El objeto afecta a cada instancia creada de ese objeto, esto permite que los métodos y propiedades del objeto principal estén presentes en cada instancia de su objeto secundario.

Si desea llamar al constructor de su clase principal en el constructor de su clase secundaria, use JavaScript call función;esto le permite llamar al constructor de la clase principal en el contexto del constructor de la clase secundaria y, por lo tanto, establecer las propiedades recién creadas en su clase secundaria a lo que están configuradas en la clase principal.

Tampoco es necesario que coloque nada donde haya especificado el *1, ya que esa línea simplemente se usa para agregar los métodos y propiedades al objeto prototipo de la clase secundaria;sin embargo, tenga en cuenta que llama al constructor de la clase principal, por lo que si hay argumentos que son fundamentales en el funcionamiento del constructor de la clase principal, debe verificar que estén presentes para evitar errores de JavaScript.

Otros consejos

Puede invocar manualmente el constructor de los padres en el constructor de la subclase de esta manera:

CHILDClass = function (basevar) {
  PARENTClass.call(this, basevar);
  // do something;
};

El truco aquí es usar el método call, que le permite invocar un método en el contexto de un objeto diferente. Ver la documentación de call para más detalles.

JavaScript no tiene soporte incorporado para jerarquías de herencia como extensión de tipo se supone que debe hacerse a través de la agregación, es decir, la adición de funcionalidad deseada directamente al objeto en sí mismo o su prototipo si la propiedad es para ser compartido entre instancias.

Sin embargo, JS es lo suficientemente potente como para hacer la implementación de otras formas de construcción de objetos posibles, incluyendo la herencia clásica.

Dado un clon función - lo cual es suficiente para agregar la herencia prototípico 'verdadero', y no bastardization de JavaScript del mismo - su exampe se puede implementar como esto:

function ParentClass(baseVar) {
    // do stuff
}

// don't overwrite the prototype object if you want to keep `constructor`
// see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
ParentClass.prototype.a = 'b';
ParentClass.prototype.c = 'd';

function ChildClass(childVar) {
    // call the super constructor
    ParentClass.call(this, childVar);
}

// don't inherit from a ParentClass instance, but the actual prototype
ChildClass.prototype = clone(ParentClass.prototype);
ChildClass.prototype.e = 'f';

También es posible añadir un poco de azúcar sintáctica para la herencia basada en la clase - mi propia aplicación se puede encontrar aquí .

El ejemplo de arriba sería entonces leer

var ParentClass = Class.extend({
    constructor: function(baseVar) {
        // do stuff
    },
    a: 'b',
    c: 'd'
});

var ChildClass = ParentClass.extend({
    e: 'f'
});

Tengo un envoltorio Javascript programación orientada a objetos que proporciona la herencia 'Clase-como' donde se pueden reemplazar los métodos de base o llame constructores de base o miembros de peso ligero.

Usted define sus clases como esto:

//Define the 'Cat' class
function Cat(catType, firstName, lastName)
{
    //Call the 'Animal' constructor.
    Cat.$baseNew.call(this, firstName, lastName);

    this.catType = catType;
}
//Extend Animal, and Register the 'Cat' type.
Cat.extend(Animal, { type: 'Cat' }, {
    hello: function(text)
    {
        return "meaoow: " + text;
    },
    getFullName: function()
    {
        //Call the base 'Animal' getFullName method.
        return this.catType + ": " + Cat.$base.getFullName.call(this);
    }
})

//It has a built-in type system that lets you do stuff like:

var cat = new Cat("ginger", "kitty", "kat");
Cat.getType()                     // "Cat"
cat.getBaseTypesAndSelf()         // ["Cat","Animal","Class"]
cat.getType()                     // "Cat"
cat.isTypeOf(Animal.getType())    // "True"

var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
dynamicCat.getBaseTypesAndSelf()  // ["Cat","Animal","Class"]
dynamicCat.getFullName()          // tab: fat cat

código fuente disponible en: clase. js

También tengo más detalles en mi blog sobre programación orientada a objetos en javascript

Sólo pensé que me gustaría mencionar algunos de los problemas con el patrón clásico que vamos a dar:

    vars
  1. referencia sobre la clase super (es) estarán disponibles como esencialmente estática en todas las instancias. Por ejemplo, si tiene arr var = [1,2,3] en el Super, y no instance_1.arr.push (4) instance_2.arr.push (5) todos estos casos se "ver" los cambios.
  2. Así que a resolver 1. con solución de Ayman, que Zakas llama "Constructor Stealing", pero ahora se llama al constructor dos veces: una para su prototipo y una vez para el robo constructor. Solución - prototipo para su uso como un ayudante inheritPrototype (mostré toda la aplicación del presente en este post: inheritPrototype método Fwiw, esto esencialmente proviene de una combinación de la página 181 del libro de Zakas y algún estudio Crockford.

  3. No hay privacidad (pero, de nuevo, que había necesidad de usar algo como el patrón del objeto duradero para conseguir esto y que puede no ser lo que quiere)

  4. Definición de objeto se deja "colgado": Solución - puso una sentencia if la comprobación de cualquiera de las funciones de su prototipo y luego definir el prototipo con un prototipo literal
  5. .

He ejemplos de todo esto sobre la ejecución de github !!!

Ha sido apenas tanto de un desafío para mí asimilo realmente ambos libros: Zakas y Crockford en la creación de objetos y la herencia. También necesitaba para tratar algunos marcos de JavaScript TDD diferentes. Así que decidí crear un ensayo sobre ambos marcos objeto de TDD y JavaScript Creación y Sucesiones. Ha ejecución de código y pruebas JSpec! Aquí está el enlace:* mi ensayo GitHub Open Source / libro

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top