Uno. Dos prototipos
Muchas personas saben que JavaScript es una herencia prototipo. Cada constructor tiene un miembro prototipo, a través del cual la herencia de JavaScript puede ser hermosa.
De hecho, este atributo solo no puede completar la herencia de JavaScript.
No diré mucho sobre el prototipo que usamos en el código. Puede verificar la información.
Otro miembro del prototipo invisible.
Cada instancia tiene un atributo prototipo que apunta al prototipo. No se puede acceder a este atributo y, por supuesto, no se puede modificar, porque esta es la base para mantener la herencia de JavaScript.
La copia del código es la siguiente:
// Declaración del constructor
function guoyansi () {}
función guoyansiex () {}
// herencia prototipo
Guoyansiex.prototype = new Guoyansi ();
// crear un objeto
var g1 = new Guoyansiex ();
var g2 = new Guoyansiex ();
Los objetos en el código anterior pueden explicarse por la siguiente figura
2. Mantenimiento prototipo
Una instancia generada por un constructor cuyo atributo de constructor siempre apunta al constructor. Pensaremos que la declaración es correcta por el momento.
La copia del código es la siguiente:
function guoyansi () {}
var obj1 = new Guoyansi ();
console.log (obj1.constructor === guoyansi); // verdadero
De hecho, el constructor en sí no tiene el atributo del constructor, entonces, ¿de dónde proviene este atributo?
La respuesta es: del prototipo.
Por lo tanto, se extraen las siguientes conclusiones
La copia del código es la siguiente: obj1.constructor === guoyansi.prototype.constructor === guoyansi
Dado que podemos encontrar el constructor a través del constructor, podemos mejorar aún más el diagrama anterior.
La copia del código es la siguiente:
función guoyansiex () {}
Guoyansiex.prototype = new Guoyansi ();
console.log (guoyansiex.constructor === guoyansiex) // falso
Según la imagen de arriba, el resultado de arriba debería ser verdadero, pero ¿por qué es falso?
Ahora haga un análisis.
El prototipo de Guoyansiex fue reescrito por la instancia de Guoyansi, por lo que el constructor en el prototipo de Guoyansiex es naturalmente una instancia de Guoyansi.
El constructor en la instancia de Guoyansi proviene de Guoyansi.prototype. Sin embargo, Guoyansi.prototype no ha sido reescrito.
Entonces el constructor de guoyansi.prototype apunta a guoyansi (constructor);
Basado en el análisis anterior, sacamos las siguientes conclusiones
La copia del código es la siguiente: guoyansiex.constructor === guoyansi.constructor === guoyansi;
Si los requisitos de la Directiva del Constructor son muy precisos durante el proceso de desarrollo, se puede realizar el siguiente procesamiento.
La copia del código es la siguiente:
/** Método 1: **/
function guoyansi () {}
función guoyansiex () {}
Guoyansiex.prototype = new Guoyansi ();
Guoyansiex.prototype.constructor = guoyansiex; // reiniciar el puntero del constructor.
La copia del código es la siguiente:
/**
Método 2
**/
function guoyansi () {}
función guoyansiex () {
this.constructor = arguments.callee;
}
Guoyansiex.prototype = new Guoyansi ();
La copia del código es la siguiente:
/**
Método 3
**/
function guoyansi () {}
función guoyansiex () {
this.constructor = guoyansiex;
}
Guoyansiex.prototype = new Guoyansi ();
3. ¿Cuál es el uso de un prototipo invisible?
Podemos operar la cadena de prototipo visible para completar nuestra herencia, por lo que no podemos ver y operar esta cadena de prototipo invisible. ¿De qué sirve?
Hay una característica en la herencia orientada a objetos: similitud. Las subclases tienen similitudes con las clases de los padres. Por lo tanto, en las subclases, no puede usar Eliminar para eliminar miembros heredados de las clases de los padres. Es decir, las subclases deben tener las características de las clases de los padres.
Para mantener esta característica, JavaScript genera una propiedad prototipo invisible dentro del objeto y no permite que el usuario acceda a ella. De esta manera, el usuario puede modificar el constructor para cualquier propósito,
No destruirá las características de la clase infantil que tiene la clase principal.
En resumen: el mecanismo de herencia prototipo de JavaScript requiere que los prototipos externos requieran que los usuarios implementen la herencia.
4. __Proto__ en el motor Firefox Spidermonkey
Aún este código.
La copia del código es la siguiente:
function guoyansi () {}
Guoyansi.prototype.age = 24;
función guoyansiex () {}
var obj1 = new Guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.prototype.constructor = guoyansiex; // reiniciar el puntero del constructor.
var obj2 = new Guoyansiex ();
Ahora quiero acceder a la edad de las propiedades del prototipo de la clase principal Guoyansi a partir de OBJ.
Esta es la idea.
Paso 1: obj2 ====> obj2.constructor.prototype
Parte 2: obj2.constructor.prototype ===> guoyansiex.prototype;
Parte 3: guoyansiex.prototype ===> obj1;
Parte 4: Obj1.Constructor ====> Guoyansi
Parte 5: guoyansi.prototype.age
Escríbelo así: console.log (obj2.constructor.prototype.constructor.prototype.age) // 24;
El resultado final es 24.
El resultado final es 24. Se puede ejecutar normalmente, pero en muchos libros, dice que después de modificar el constructor, el nivel no puede encontrar el prototipo en la clase principal. No sé qué está pasando.
Suficiente de un atributo más conciso en Firefox._proto_
Por defecto, Spidermonkey agrega un atributo llamado _Proto_ a cualquier objeto creado, que apunta al prototipo utilizado por el constructor.
De hecho, es la cadena prototipo invisible que mencionamos anteriormente, pero es solo una divulgación disfrazada en este lugar.
Puedes acceder a la edad de esta manera
console.log (obj2 .__ proto __.__ proto __. edad); // 24
De hecho, esto accede con éxito al atributo prototipo de la clase principal, pero este atributo solo es aplicable a Firefox, y habrá errores en otros navegadores.
En E5, el objeto se extiende a Object.getPrototipof (), y puede acceder a todos los prototipos de clase principal.
La copia del código es la siguiente:
function guoyansi () {}
Guoyansi.prototype.age = 24;
función guoyansiex () {}
var obj1 = new Guoyansi ();
Guoyansiex.prototype = obj1;
Guoyansiex.prototype.constructor = guoyansiex; // reiniciar el puntero del constructor.
var obj2 = new Guoyansiex ();
var proto = object.getPrototypeOf (obj2);
while (proto) {
console.log (proto.constructor);
proto = object.getPrototypeOf (proto);
}
console.log ("Prototipo de objeto"+Proto);
El resultado es: guoyansiex
Guoyansi
Objeto
Prototipo nulo para objeto
Personalmente, creo que estas deberían considerarse una de las esencias del JavaScript orientado a objetos. Consultelo usted mismo y úselo en su propio proyecto de acuerdo con sus necesidades.