Prefacio
Vi una pregunta como esta en SegmentFault:
var f = function () {}; object.prototype.a = function () {}; Function.prototype.b = function () {}; var f = new f ();P: ¿Puede F obtener A y B? ¿Cuál es el principio?
A primera vista, estaba realmente confundido. Después de un cuidadoso estudio, descubrí que todavía no entendía el prototipo a fondo, así que lo resumí y llené un agujero ~
Función y objeto
Antes de resolver el problema, hablemos sobre el prototipo, la cadena de prototipos y la relación entre la función y el objeto, que también es el foco de este artículo.
prototipo
Al crear una función, se creará automáticamente un objeto prototipo, a la que se puede acceder a través de la propiedad prototipo de la función.
Cree un objeto de instancia del constructor, que contendrá un puntero (propiedad interna) dentro de él, apuntando al objeto prototipo del constructor. ECMA-262 La quinta edición de este puntero se llama [[prototipo]]. Aunque no hay una forma estándar de acceder a [[prototipo]] en scripts, Firefox, Safari y Chrome admite una propiedad __proto__ en cada objeto para acceder al objeto prototipo de su constructor.
Déjame decir algo importante de nuevo:
El constructor accede al objeto prototipo a través de la propiedad prototipo.
El objeto de instancia accede al objeto prototipo a través del atributo interno [[prototipo]], y el navegador implementa el atributo _proto_ para el objeto de instancia para acceder al objeto prototipo.
var f = function () {}; var f = new f (); // suponiendo que el objeto prototipo de f es p, entonces // f.prototype === P; // f .__ proto__ === P;Repita nuevamente. . El prototipo se refiere a la relación entre el constructor y el objeto prototipo, y __proto__ se refiere a la relación entre el objeto de instancia y el objeto prototipo.
Cadena prototipo
La clase A hereda B, B hereda C ... De hecho, hay un objeto prototipo con un puntero que apunta a B en el objeto prototipo de A y un objeto prototipo con un puntero que apunta a C en el objeto prototipo ... Tenga en cuenta que es la conexión entre los objetos prototipo. No hay relación entre los tres constructores de ABC, por lo que se llama "cadena prototipo" ~
Suponiendo que A es un objeto de instancia de A, la cadena prototipo de A se muestra en la línea púrpura en la figura a continuación, y la línea naranja conecta el constructor y su objeto prototipo.
Como se puede ver en la figura, el final de la cadena prototipo es objeto.prototipo .__ Proto__ es decir, nulo. Cuando busque una propiedad o método de A, primero busque si una misma tiene o no. Si no, busque a lo largo de la cadena prototipo hasta que se encuentre o finalmente regrese a Undefined después de NULL.
Función y objeto
La relación entre la función y el objeto está un poco enredado:
El objeto es un constructor. Dado que es una función, es el objeto de instancia de función; La función es un constructor, pero la función.prototype es un objeto. Como es un objeto, es el objeto de instancia del objeto.
Todos los objetos son instancias de objetos, y todas las funciones son instancias de función.
El objeto es una instancia de función, y funct.prototype es una instancia de objeto.
La relación entre los dos se muestra en la figura a continuación.
Como se puede ver, el objeto como un constructor, tiene el atributo prototipo que apunta a Object.Prototype, y como objeto de instancia, tiene el objeto .__ Proto__ apuntando a function.prototype. La función es un constructor, tiene un atributo prototipo que apunta a function.prototype, y la función es una función, y también es una instancia de función, por lo que tiene función .__ Proto__ apuntando a function.prototype, entonces función .__ proto__ === Función.prototype es verdadero.
Se puede verificar debajo de la consola cromada, como se muestra en la figura.
Análisis de la pregunta original
La mejor manera de resolver el problema de la cadena prototipo es dibujar una imagen. Después del análisis anterior, esta imagen no debería ser un problema, como sigue ~
La cadena prototipo de F es dibujada por una línea azul, por lo que F puede acceder a, pero B no puede acceder.
Si no dibuja una imagen, a primera vista, puede pensar que F puede acceder b. Puede ser como yo que F.Prototype apunte a funciones.
Por lo tanto, debe dibujar una imagen cada vez que el problema de la cadena prototipo sea ~
Tema extendido
En la pregunta anterior, F solo puede acceder a, pero no b. Pero F puede acceder a A y B. Si modifica la pregunta a lo siguiente, ¿cuál es el resultado de fb ()? ¿Por qué? Puedes pensar en ello ~
var f = function () {}; object.prototype.a = function () {}; Function.prototype.b = function () {console.log ('f .__ proto__')}; F.prototype.b = function () {console.log ('f.prototype');};Resumir
Después de leer esto, ¿ha encontrado una característica especial de la función?
Para un objeto general, solo hay un atributo __proto__ utilizado para acceder al objeto prototipo de su constructor, y para una función, es tanto una función como un objeto.
Como función, nace con un atributo prototipo que apunta a su prototipo de nombre de función de objeto.prototype.
Como objeto de instancia de función, tiene el atributo __proto__ que apunta a function.prototype
Por lo general, estas dos propiedades apuntan a dos objetos, pero ambas propiedades de la función apuntan a las mismas, ambas apuntan a función.
Para la función A (), los métodos en A.prototipo son para llamar a su objeto de instancia y no serán utilizados por sí mismo; Cuando A se ejecuta como instancia, se llaman a los métodos en un .__ Proto__. En otras palabras, cuando se usa como constructor, se toma la cadena de prototipo A. y los métodos y atributos se asignan a sus ejemplos; Cuando se usa como objeto, se toma la cadena A .__ Proto__. En diferentes escenarios, no es incorrecto distinguir su identidad.
Después de todo el artículo, siento que lo que dije es bastante persistente ... por favor corríjeme si hay alguna deficiencia ~ En cuanto a la pregunta, realmente no sé cómo llamarlo. .
Que este artículo te traiga algunas ganancias después de leerlo ~ ^_ ^
Gracias por su apoyo a este sitio web. ¡Continuaremos actualizando información relevante en el futuro para ayudarlo a aprender y comprender esta parte del conocimiento!