La herencia en js se puede dividir en dos tipos: suplantación de objetos y encadenamiento de prototipos.
1. La suplantación de objetos incluye tres tipos : método de atributo temporal, método call() y apply()
1. Método de atributo temporal
Copie el código de código de la siguiente manera:
función Persona(nombre){
this.nombre = nombre;
this.say = función(){
alerta('Mi nombre es '+este.nombre);
}
}
función F2E(nombre,id){
this.temp = Persona;
this.temp(nombre);
eliminar this.temp;
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
var simón = nuevo F2E('Simón',9527);
simon.say();
simon.showId();
2.método call()/apply()
Básicamente, cambia el puntero de este puntero.
Copie el código de código de la siguiente manera:
función Persona(nombre){
this.nombre = nombre;
this.say = función(){
alerta('Mi nombre es '+este.nombre);
}
}
función F2E(nombre,id){
Person.call(this,name); //el método apply() cambió a Person.apply(this,new Array(name));
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
var simón = nuevo F2E('Simón',9527);
simon.say();
simon.showId();
Desventajas: primero veamos este diagrama de asignación de memoria:
En el concepto OO, después de crear una instancia de new, el objeto forma su propio espacio en la memoria del montón. Vale la pena señalar que este segmento de código. Los métodos miembro existen en este segmento de código y los métodos se comparten. El problema está aquí: cuando se hereda mediante la suplantación de objetos, todos los métodos miembros apuntan a esto, es decir, después de la nueva, cada instancia tendrá este método miembro, que no se comparte, lo que genera una gran cantidad de memoria. Y mediante la suplantación de objetos, las variables y métodos definidos mediante el prototipo no se pueden heredar. Por ejemplo, el siguiente código provocará un error:
Copie el código de código de la siguiente manera:
función Persona(nombre){
this.nombre = nombre;
this.say = función(){
alerta('Mi nombre es '+este.nombre);
}
}
Persona.prototipo.edad = 20;
Person.prototype.sayAge = function(){alert('Mi edad es '+this.age)};
función F2E(nombre,id){
Persona.apply(this,new Array(nombre));
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
var simón = nuevo F2E('Simón',9527);
simon.sayAge(); //Prompt TypeError: simon.sayAge no es una función
2. Método de cadena de prototipo
Copie el código de código de la siguiente manera:
función Persona(){
this.name = 'Simón';
}
Persona.prototipo.say = función(){
alerta('Mi nombre es '+este.nombre);
}
función F2E(identificación){
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
F2E.prototipo = nueva Persona();
var simón = nuevo F2E(9527);
simon.say();
simon.showId();
alert(simon.hasOwnProperty('id')); //Comprueba si es propiedad suya
A continuación, siga el ejemplo anterior para comprender los siguientes conceptos de la cadena de prototipos js:
La cadena de prototipos puede entenderse como: cada objeto en js tiene un atributo __proto__ oculto. El atributo __proto__ de un objeto instanciado apunta al método prototipo de su clase, y este método prototipo se puede asignar a otro objeto instanciado, el __proto__ de. este objeto necesita apuntar a su clase, formando así una cadena, que es la
Copie el código de código de la siguiente manera:
F2E.prototipo = nueva persona()
Esta frase es la clave. Cuando un objeto js lee un determinado atributo, primero buscará sus propios atributos. Si no hay atributos, buscará los atributos del objeto en la cadena del prototipo. En otras palabras, los métodos de la cadena de prototipos se pueden compartir, lo que resuelve el problema de la suplantación de objetos y el desperdicio de memoria.
Ahora hablemos de las desventajas:
La desventaja es obvia. La herencia de la cadena de prototipo significa que los parámetros no se pueden pasar a la clase principal al crear una instancia de una subclase. Es por eso que la función Person() en este ejemplo no tiene parámetros y se escribe directamente como this.name="Simon". El siguiente código no logrará el efecto deseado:
Copie el código de código de la siguiente manera:
función Persona(nombre){
this.nombre = nombre;
}
Persona.prototipo.say = función(){
alerta('Mi nombre es '+este.nombre);
}
función F2E(nombre,id){
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
F2E.prototipo = nueva Persona();
var simón = nuevo F2E("Simón",9527);
simon.say();
simon.showId();
función Persona(nombre){
this.nombre = nombre;
}
Persona.prototipo.say = función(){
alerta('Mi nombre es '+este.nombre);
}
función F2E(nombre,id){
this.id = identificación;
this.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
}
F2E.prototype = new Person(); //El valor no se puede pasar aquí, ni this.name ni name funcionarán. Es posible escribir directamente F2E.prototype = new Person('wood'), pero en este caso simon. decir() se convierte en Mi nombre es madera
var simón = nuevo F2E("Simón",9527);
simon.say(); //Emergente Mi nombre no está definido
simon.showId();
Finalmente, permítanme resumir lo que creo que es una mejor manera de implementar la herencia. Las variables miembro usan la suplantación de objetos y los métodos miembros usan el encadenamiento de prototipos.
Copie el código de código de la siguiente manera:
función Persona(nombre){
this.nombre = nombre;
}
Persona.prototipo.say = función(){
alerta('Mi nombre es '+este.nombre);
}
función F2E(nombre,id){
Persona.llamada(este,nombre);
this.id = identificación;
}
F2E.prototipo = nueva Persona();
//Tenga en cuenta un detalle aquí: showId no se puede escribir delante de F2E.prototype = new Person();
F2E.prototype.showId = función(){
alert('Buenos días, señor, mi número de trabajo es '+this.id);
}
var simón = nuevo F2E("Simón",9527);
simon.say();
simon.showId();