La herencia en JavaScript es bastante extraña. No puede implementar la herencia de la interfaz y solo puede confiar en la herencia prototipo.
Cadena prototipo
Un prototipo es un objeto. La instancia creada a través del constructor tendrá un puntero al prototipo para obtener las propiedades y métodos del prototipo. De esta manera, el objeto de instancia tiene el método de atributo del constructor y el método de atributo del prototipo, y luego señala el prototipo del constructor que debe heredarse en esta instancia, para que se puedan heredar todos los métodos de atributo de la instancia.
Vea el siguiente código de demostración:
//Declare the superclass, add relevant properties and methods through constructors and prototypes function Super(){ this.property = true;}Super.prototype.getSuperValue = function() { return this.property;};//Declare the constructor function SubType() { this.subproperty = false;}//Point the prototype of the subclass to the instance of the superclase y obtenga todo en el superclase subtype.prototype = new super (); subtype.prototype.constructor = subtype; subtype.prototype.getSubValue = function () {return this.subProperty;}; // Cree un objeto de un subclass para probar si está inheredando a los métodos y atribuye los métodos nuevos y atributas; console.log (instance.getSuperValue ());El prototipo predeterminado de todas las funciones es una instancia de objeto, por lo que el prototipo predeterminado contendrá un puntero interno a Object.prototype.
Use InstanceOf e IsPrototypeOf para determinar la relación entre prototipos e instancias:
instancia de instancia de objeto; objeto.prototype.isprototypeOf (instancia);
Al usar cadenas prototipo, debe definir el método cuidadosamente. Las subclases deben reescribir un método o extensión de Supertype, y deben colocarse después de la declaración que reemplaza el prototipo, para que pueda entrar en vigencia. Además, al heredar a través de una cadena prototipo, no puede usar literales de objetos para crear un método prototipo, que anulará la cadena prototipo:
...... subtype.prototype = new Super (); subtype.prototype = {....};Esto reemplaza el puntero para apuntar al nuevo objeto, reescribiendo la cadena prototipo.
El método de herencia de las cadenas prototipo es defectuosa, y hay dos problemas principales:
1. Desde un prototipo que contiene el valor del tipo de referencia, será compartido por todas las instancias.
Como se mencionó en el artículo anterior, los atributos prototipo que contienen valores de tipo de referencia serán compartidos por todas las instancias. Se modificará una instancia y las otras instancias cambiarán en consecuencia. Por lo tanto, los atributos deben definirse en el constructor. Cuando la cadena prototipo hereda, sin importar si los atributos en la superclase se definen en el constructor o en el prototipo, todos se convierten en objetos de instancia y son heredados por subclases, por lo que tienen un impacto en las instancias de la subclase.
2. Al crear una instancia de un subtipo, los parámetros no se pueden pasar al constructor Supertype.
La herencia de la cadena prototipo apunta directamente al prototipo de subclase a la instancia de la superclase, y en este momento, los parámetros se pueden pasar a la superclase. Sin embargo, cuando una subclase crea una instancia, solo puede pasar parámetros al constructor de la subclase, pero no al constructor de la superclase.
Por lo tanto, en aplicaciones prácticas, las cadenas prototipo rara vez se usan solas.
Algunas prácticas de código relacionado
Identificar un atributo prototipo
función HasPrototyPeProperty (objeto, nombre) {nombre de retorno en objeto &&! Object.HasownProperty (nombre);}Uso de objetos prototipo en constructores
Function Person (name) {this.name = name;} persona.prototype = {constructor: persona, sayname: function () {console.log (this.name); }, toString: function () {}}; var persona1 = nueva persona ('nicholas'); var persona2 = nueva persona ('greg); console.log (persona1 instancia de persona); // trueConsole.log (persona1.constructor === Persona); // trueConsole.log (persona1.constructor === Persona); // trueconsole.log (persona1.constructor === objeto); // falseconsole.log (persona2 instancia de persona); // trueConsole.log (persona2.constructor === Persona); // trueConsole.log (persona2.constructor === objeto); // FALSOHerencia de objetos
var persona1 = {nombre: 'nicholas', sayname: function () {console.log (this.name); }}; var persona2 = objeto.create (persona1, {nombre: {configurable: true, enumerable: true, valor: 'greg', writable: true}}); persona1.sayname (); // nicholasperson2.sayname (); // gregconsole.log (persona1.hasownproperty ('sayname')); // trueConsole.log (persona1.isPropertyOf (persona2)); // trueconsole.log (persona2.hasownproperty ('sayname')); // FALSOModo de módulo
var persona = (function () {var a age = 25; function getAge () {return Age;} function growolder () {age ++;} return {name: 'nicholas', getage: getage, growolder: growolder};} ());Constructor de ámbitos
Function Person (name) {this.name = name;} persona.prototype.sayname = function () {console.log (this.name);}; var persona1 = persona ('nicholas'); console.log (persona1 instancia de la persona); // Falseconsole.log (typeof persona1); // UndefinedConsole.log (nombre); // nicholas