JavaScript utiliza herencia prototípica de forma predeterminada. Aunque no existe el concepto de clase, su función puede actuar como constructor. El constructor combinado con this y new puede construir una clase similar a Java. Por lo tanto, JavaScript puede emular la herencia basada en clases extendiéndose.
JavaScript, al igual que otros lenguajes orientados a objetos, utiliza referencias para tipos de objetos. La variable que contiene el objeto es solo una dirección, mientras que los datos de tipo básico son el valor. Al almacenar objetos en prototipos, pueden surgir algunos inconvenientes.
Veamos primero el primer ejemplo.
Copie el código de código de la siguiente manera:
var crear = función() {
función Fn() {}
función de retorno (padre) {
Fn.prototipo = padre
devolver nueva Fn
}
}()
var padre = {
nombre: 'gato',
edad: 30,
está casado: falso
}
var hijo = crear (padre)
consola.log(niño)
La función de la herramienta de creación implementa una herencia de prototipo básica. Cada vez que se llama a crear, se copiará un nuevo objeto según el objeto principal. Todas las propiedades del nuevo objeto provienen del objeto principal. Aquí el padre tiene tres atributos, todos los cuales son tipos de datos básicos: cadena, número y booleano.
Ahora modifique al niño para ver si afectará al padre.
Copie el código de código de la siguiente manera:
niño.nombre = 'lirio'
niño.edad = 20,
niño.está casado = verdadero
consola.log(niño)
consola.log(padre)
Los resultados son los siguientes
Es decir, modificar al hijo no afectará al padre.
Veamos otro ejemplo
Copie el código de código de la siguiente manera:
var crear = función() {
función Fn() {}
función de retorno (padre) {
Fn.prototipo = padre
devolver nueva Fn
}
}()
var padre = {
datos: {
nombre: 'gato',
edad: 30,
está casado: falso
},
idioma: ['Java']
}
var hijo = crear (padre)
child.data.name = 'lirio'
niño.datos.edad = 20
child.data.isMarried = verdadero
niño.idioma.push('javascript')
consola.dir(niño)
consola.dir(padre)
Tenga en cuenta que los dos atributos de padre aquí, datos e idioma, son tipos de referencia, uno es un objeto y el otro es una matriz. El hijo aún hereda del padre y luego se modifica. Los resultados son los siguientes.
Como puede ver, el padre también ha sido modificado en este momento y el nombre, edad, etc. del niño son los mismos. Esto es algo a tener en cuenta cuando se utiliza la herencia de prototipos.
Una mejor manera de utilizar la herencia es:
1. Los atributos de datos adoptan la herencia de clases (pendiente de esto), por lo que también se pueden configurar mediante parámetros cuando son nuevos.
2. El método adopta una herencia prototípica, lo que puede ahorrar memoria. Al mismo tiempo, anular métodos por subclases no afectará a la clase principal.
La siguiente es una función de herramienta de escritura que satisface los dos puntos anteriores.
Copie el código de código de la siguiente manera:
/**
* @param {String} nombre de clase
* @param {Cadena/Función} superCls
* @param {Función} fábrica
*/
función $clase(nombre, superclase, fábrica) {
if (superClase === '') superClase = Objeto
funciónclazz() {
if (tipo de esto.init === 'función') {
this.init.apply(esto, argumentos)
}
}
var p = clazz.prototype = nuevos superCls
clazz.prototype.constructor = clazz
clazz.prototype.className = nombre de clase
var supr = superCls.prototipo
ventana[nombredeclase] = clazz
llamada.fábrica(p, supr)
}
Al colocar un tipo de objeto en el prototipo de una clase principal, tenga cuidado cuando las subclases lo modifiquen. En este caso, se modificarán todas las instancias de las subclases que heredan de la clase principal. Y los errores causados por esto son muy difíciles de encontrar.
Se agregó una nueva API a ES5 para implementar la herencia prototípica: Object.create. Puede usarlo para reemplazar la función de creación autoimplementada anterior, de la siguiente manera
Copie el código de código de la siguiente manera:
var padre = {
nombre: 'gato',
edad: 30,
está casado: falso
}
var hijo = Objeto.create(padre)
consola.log(niño)