El concepto de herencia JS
Los siguientes dos métodos de herencia comúnmente utilizados en JS:
Herencia de la cadena prototipo (herencia entre objetos)
Herencia clásica (herencia entre constructores)
Dado que JS no es un lenguaje verdaderamente orientado a objetos como Java, JS está basado en objetos y no tiene un concepto de clases. Por lo tanto, si desea implementar la herencia, puede usar el mecanismo prototipo prototipo de JS o utilizar los métodos de aplicación y llamada para implementarlo
En un lenguaje orientado a objetos, usamos clases para crear un objeto personalizado. Sin embargo, todo en JS es un objeto, entonces, ¿qué método se puede usar para crear un objeto personalizado? Esto requiere el prototipo JS:
Simplemente podemos considerar el prototipo como una plantilla. Los objetos personalizados recién creados son una copia de esta plantilla (prototipo) (en realidad no es una copia sino un enlace, pero este tipo de enlace es invisible. Hay un puntero __proto__ invisible dentro del objeto recién instanciado, apuntando al objeto prototipo).
JS puede simular e implementar las funciones de las clases a través de constructores y prototipos. Además, la implementación de la herencia del tipo JS también se logra dependiendo de las cadenas prototipo.
Herencia prototipo y herencia de clase
La herencia clásica es la llamada de un constructor supertipo dentro del constructor subtipo.
La herencia de clase estricta no es muy común, y generalmente se usa en combinación:
La copia del código es la siguiente:
función super () {
this.colors = ["rojo", "azul"];
}
función sub () {
Super.call (esto);
}
La herencia prototipo es crear un nuevo objeto con la ayuda de objetos existentes y apuntar el prototipo de la subclase a la clase principal, que es equivalente a agregar la cadena prototipo de la clase principal.
Herencia de la cadena prototipo
Para que una clase infantil herede las propiedades de la clase principal (incluidos los métodos), primero es necesario definir un constructor. Luego, asigne una nueva instancia de la clase principal al prototipo del constructor. El código es el siguiente:
La copia del código es la siguiente:
<script>
función parent () {
this.name = 'Mike';
}
function child () {
this.age = 12;
}
Child.prototype = new Parent (); // El niño hereda de los padres y forma una cadena a través del prototipo.
VAR test = new Child ();
alerta (test.age);
alerta (test.name); // Obtener atributos heredados
// Continuar heredando la cadena prototipo
function Brother () {// Brother Construct
this.weight = 60;
}
Hermano.prototype = new Child (); // Continuar con prototipo de herencia
var hermano = nuevo hermano ();
alerta (hermano.name); // heredar padre e hijo, Mike aparece
alerta (hermano.
</script>
A la herencia de la cadena prototipo anterior todavía le faltan un enlace, es decir, y todos los constructores se heredan del objeto. El objeto heredado se completa automáticamente y no requiere herencia manual por nosotros mismos. Entonces, ¿cuál es su relación subordinada?
Determinar la relación entre prototipo e instancia
Hay dos formas de determinar la relación entre un prototipo y una instancia. Operator instanceOf e isPrototypeOf () Métodos:
La copia del código es la siguiente:
alerta (instancia de hermano de objeto) // Verdadero
alerta (prueba de prueba de hermano); // falso, la prueba es la superclase del hermano
alerta (Instancia de Hermano de niño); // Verdadero
alerta (instancia hermano del padre); // Verdadero
Mientras sea un prototipo que aparece en la cadena prototipo, se puede decir que es el prototipo de la instancia derivada de la cadena prototipo. Por lo tanto, el método ISPrototypeOf () también devolverá verdadero.
En JS, la función hereditaria se llama supertipo (clase principal, clase base y también) y la función heredada se llama subtipo (subclase, clase derivada). El uso de la herencia prototipo implica principalmente dos problemas:
Primero, la reescritura literal de los prototipos romperá la relación, usará el prototipo del tipo de referencia y el subtipo no puede pasar los parámetros al supertipo.
La pseudo-clase resuelve el problema del intercambio de referencias y los supertipos no pueden aprobar argumentos. Podemos usar la tecnología de "constructor de préstamo".
Constructor de préstamo (herencia clásica)
La copia del código es la siguiente:
<script>
función parent (edad) {
this.name = ['Mike', 'Jack', 'Smith'];
this.age = edad;
}
función de niño (edad) {
Parent.call (esta, edad);
}
VAR test = New Child (21);
alerta (test.age); // 21
alerta (test.name); // Mike, Jack, Smith
test.name.push ('bill');
alerta (test.name); // Mike, Jack, Smith, Bill
</script>
Aunque los constructores de préstamos resolvieron los dos problemas en este momento, sin prototipos, no hay forma de reutilizar, por lo que necesitamos una cadena prototipo + patrón de constructor de préstamo. Este patrón se llama herencia combinada.
Herencia combinada
La copia del código es la siguiente:
<script>
función parent (edad) {
this.name = ['Mike', 'Jack', 'Smith'];
this.age = edad;
}
Parent.prototype.run = function () {
devuelve this.name + 'son' + this.age;
};
función de niño (edad) {
Parent.call (this, edad); // El objeto se hace pasar por parámetros a los supertipos
}
Child.prototype = new Parent (); // herencia de la cadena prototipo
VAR test = New Child (21); // escribir nuevo padre (21) está bien
alerta (test.run ()); // Mike, Jack, Smith son ambos21
</script>
La herencia combinada es un método de herencia relativamente comúnmente utilizado. La idea detrás de esto es usar la cadena prototipo para implementar la herencia de las propiedades y métodos prototipo, e implementar la herencia de las propiedades de instancia mediante constructores de préstamos. De esta manera, la multiplexación de funciones se logra definiendo métodos en el prototipo y asegurando que cada instancia tenga sus propias propiedades.
Uso de la llamada (): llame a un método de un objeto y reemplace el objeto actual con otro objeto.
La copia del código es la siguiente:
llamar ([thisObj [, arg1 [, arg2 [, [, .argn]]]]])
Herencia prototipo
Esta forma de heredar la creación de nuevos objetos basados en objetos existentes sin crear tipos personalizados se llama herencia prototipo
La copia del código es la siguiente:
<script>
función obj (o) {
función f () {}
F.Prototype = O;
devolver nuevo f ();
}
var box = {
Nombre: 'Trigkit4',
arr: ['hermano', 'hermana', 'baba']
};
var b1 = obj (box);
alerta (b1.name); // trigkit4
b1.name = 'Mike';
alerta (b1.name); // Mike
alerta (b1.arr); // hermano, hermana, baba
b1.arr.push ('Padres');
alerta (b1.arr); // hermano, hermana, baba, padres
var b2 = obj (box);
alerta (b2.name); // trigkit4
alerta (b2.arr); // hermano, hermana, baba, padres
</script>
La herencia prototipo primero crea un constructor temporal dentro de la función obj (), luego usa el objeto pasado como prototipo del constructor y finalmente devuelve una nueva instancia de este tipo temporal.
Herencia parásita
Este método de herencia combina el modelo Prototype + Factory, con el propósito del proceso de creación de encapsulación.
La copia del código es la siguiente:
<script>
función create (o) {
var f = obj (o);
f.run = function () {
devolver esto.arr; // Del mismo modo, las referencias se compartirán
};
regresar f;
}
</script>
Pequeños problemas con la herencia combinada
La herencia combinada es el modo de herencia más utilizado en JS, pero el supertipo de herencia combinada se llamará dos veces durante el uso; Una vez al crear un subtipo, y el otro está dentro del constructor de subtipo.
La copia del código es la siguiente:
<script>
función parent (nombre) {
this.name = name;
this.arr = ['hermano', 'hermana', 'padres'];
}
Parent.prototype.run = function () {
devolver esto.name;
};
Function Child (nombre, edad) {
Parent.call (this, edad); // la segunda llamada
this.age = edad;
}
Child.prototype = new Parent (); // La primera llamada
</script>
El código anterior es la herencia de combinación anterior, por lo que la herencia de combinación parásita resuelve el problema de dos llamadas.
Herencia de combinación parásita
La copia del código es la siguiente:
<script>
función obj (o) {
función f () {}
F.Prototype = O;
devolver nuevo f ();
}
function create (parent, test) {
var f = obj (parent.prototype); // crear un objeto
F.Constructor = test; // Object mejorado
}
función parent (nombre) {
this.name = name;
this.arr = ['hermano', 'hermana', 'padres'];
}
Parent.prototype.run = function () {
devolver esto.name;
};
Function Child (nombre, edad) {
Parent.call (esto, nombre);
this.age = edad;
}
herhheritprototype (padre, hijo); // La herencia se realiza por aquí
Var test = new Child ('trigkit4', 21);
test.arr.push ('sobrino');
alerta (test.arr); //
alert (test.run ()); // Solo se comparte el método
var test2 = new Child ('Jack', 22);
alerta (test2.arr); // Resuelve el problema de la cita
</script>
llamar y aplicar
Las funciones globales se aplican y la llamada se puede utilizar para cambiar la señalización de esto en la función, de la siguiente manera:
La copia del código es la siguiente:
// Definir una función global
función foo () {
console.log (this.fruit);
}
// Definir una variable global
var fruit = "manzana";
// Personalizar un objeto
var paquete = {
Fruta: "Naranja"
};
// equivalente a Window.foo ();
foo.apply (ventana); // "Apple", esto es igual a la ventana
// este === paquete en foo
foo.apply (paquete); // "naranja"