Una comprensión profunda de los objetos prototipo de JavaScript y las cadenas de prototipos.

Objeto prototipo y cadena prototipo


Uno de los núcleos de JavaScript es también un punto de conocimiento que debemos dominar. En primer lugar, vacunarse, esto implica muchos puntos de conocimiento, que son muy abstractos y difíciles de entender, pero intentaré explicarlo claramente, y el resto depende de su comprensión.

Permítanme primero enumerar algunas palabras clave que aparecerán (si las entiende todas, no es necesario que lea este artículo):

  • Objeto prototipo , cadena prototipo , constructor

  • [[Prototipo]]prototipo__proto__esto


1. Vinculación dinámica de este (conocimientos preliminares)

Antes de aprender prototipos, debemos entender el enlace dinámico de esto en JavaScript. En lenguajes de programación como Java o C++, esto representa la referencia del objeto de instancia actual, y esta referencia está vinculada al objeto actual y no cambiará. Pero en JavaScript, el apuntar de esto no es lo mismo, veamos primero un ejemplo simple:

var date = "Monday";		//这实际上就是 var window.date = "Monday";

function func() {
    
    
    /* 你可能会好奇,这只是一个函数,哪来的 this?
    还记得 window 全局对象吗,this 默认绑定的就是它,所以下面这句话实际上输出的是 window.date */
    console.log("Today is " + this.date);
}

func();

//接下来我们写一个对象,往对象中添加 date 属性
var obj = {
    
    
    date: "Sunday",
    func: function () {
    
    
        //此时的 this 绑定的就是 obj 对象
        console.log("Today is " + this.date);
    }
}
obj.func();

Resultados de la salida de la consola (aquí imprimí este punto de las dos funciones por cierto):

36


Primero digamos mucho sobre esto, por el momento, solo necesitamos saber dos cosas:

  • esto no se refiere a la función en sí
  • El enlace de esto ocurre cuando se llama a la función, y la ubicación a la que apunta depende completamente de dónde se llama la función.


2. El prototipo de la función

En JavaScript, cada función tiene una propiedad prototipo, que apunta al objeto prototipo de la función, y luego este objeto tiene una propiedad constructora, que apunta a la función misma . Hay varios conceptos nuevos que aparecen seguidos en una oración. Si nada más, deberías estar mareado. Está bien. Usemos una imagen para representarlo:

37


Dar vueltas en círculo, volviendo a la función en sí, ¿es útil? Eso debe ser útil, si es inútil, ¿la gente hará esto?


Todos sabemos que cuando se crea un objeto de instancia, se llama a su constructor. Entonces, dado que el prototipo de una función en JavaScript apunta a un objeto, y este objeto también tiene un constructor, ¿podemos usar la función para crear un objeto de instancia?

Si puede entender lo anterior, entonces ha tenido éxito en el primer paso. El segundo paso es cómo crear el problema. En realidad, es muy simple. Use new (sí, new existe en JavaScript, los estudiantes que tienen miedo de new, Do no escape), deje que el nombre del objeto = nuevo nombre de la función () , a primera vista la función no tiene un constructor, pero su objeto prototipo tiene, cuando tenemos el nuevo nombre de la función (), la función encontrará su objeto prototipo a través del atributo prototipo , el objeto prototipo llama a su constructor, que está representado por el código como func.prototype.constructor. Debes haberlo descubierto si eres inteligente. Oye, ¿no es esa la función en sí? Si no me crees, prueba consola .log(func === func. prototipo.constructor) para ver si el resultado es verdadero. En resumen, podemos usar la función como constructor y usar la nueva palabra clave para crear un objeto de instancia

No es suficiente simplemente crear un objeto de instancia, porque dicho objeto no tiene propiedades ni métodos. En este momento, creemos que el constructor a menudo va de la mano con esto, y porque el constructor aquí es la función misma, ¿Se puede usar directamente en la función? La respuesta es sí, y es usar el problema de enlace dinámico de esto en JavaScript. Como se mencionó anteriormente, esto está vinculado al objeto de la ventana de forma predeterminada, pero en el momento de la nueva, dado que el objeto prototipo está llamando al constructor (es decir, la función en sí), en este momento estará vinculado al objeto de instancia para be created , que se establece de forma natural El objeto es la propiedad del objeto Si no puede entender bien esta oración, recuerde leer el código cuidadosamente.

Hemos resuelto el problema de las propiedades, pero al final todavía necesitamos un método, ya que queremos que el objeto prototipo de la función tenga métodos, es inútil establecerlo directamente en la función. ¿Entonces que deberia hacer ahora? De hecho, es muy simple, solo necesitamos usar el atributo prototipo para encontrar el objeto prototipo de la función, y usar directamente el método de objeto.nombre del método = función (parámetro) {} (si lo olvida, mire el conocimientos básicos sobre objetos de JavaScript)

//对了,这里说一个规范,当这个函数我们准备充当构造函数的时候,需要大写首字母哦
function Person(obj) {
    
    
    // || 右边的代表默认值,即不赋值的情况下属性的默认值
    this.name = obj.name || "UnName";
    this.age = obj.age || "-1";
}

//直接在函数上面添加方法(错误)
//Person.run = function(){
    
    
//	console.log(this.name + " 在跑步");
//}

//使用 prototype 增加 Person 原型对象的方法(正确)
Person.prototype.run = function () {
    
    
    console.log(this.name + " 在跑步");
}

Person.prototype.eat = function () {
    
    
    console.log(this.name + " 在吃饭");
}

let Mike = new Person({
    
    name: "Mike", age: 21});
Mike.eat();					//输出 Mike 在吃饭
Mike.run();					//输出 Mike 在跑步

Ok, entonces podemos actualizar la imagen de arriba:

202201181415616.jpg



3. El [[Prototipo]] del objeto ( __proto__ )

Finalmente, cuando se trata de objetos, cada objeto en JavaScript tiene un atributo oculto llamado [[Prototype]] (¡asegúrese de no quitar los corchetes en ambos lados! Esto también se llama __proto__ en la mayoría de los navegadores como Chrome ), [[Prototype ]] puede entenderse como un puntero, que apunta a un objeto, que es el objeto prototipo , sí, es el objeto prototipo de la función. Cuando JavaScript no puede encontrar una propiedad o método en el objeto actual, delegará a su objeto prototipo a través de [[Prototipo]] (delegación: un entendimiento simple es encontrar las propiedades y métodos que queremos en el objeto prototipo)

Luego continuamos actualizando el gráfico:

202201241338110.jpg


De la figura anterior, podemos ver que el prototipo de la función y el [[Prototipo]] del objeto apuntan al mismo objeto prototipo.Veamos si es:

//还是用上边 Person 代码哈,浏览器中 __proto__ 就是 [[Prototype]]
console.log(Mike.__proto__ === Person.prototype);		//输出 true,自己动手,丰衣足食


4. Cadena prototipo

¿Qué es la cadena de prototipo?Cuando queremos acceder a una propiedad en un objeto (supongamos que el objeto A), JavaScript primero verificará si la propiedad de destino existe en el mismo objeto A. Si no existe, lo verificará a través de su [[ Prototipo]] El objeto prototipo del objeto B (suponiendo que el objeto B) no tiene el atributo a buscar, si aún no existe, continúe buscando el objeto prototipo del objeto B (suponiendo que el objeto C) exista el atributo de destino hasta se encuentra el atributo o se encuentra nulo (es decir, se encuentra el objeto, pero aún no se encuentra la propiedad), donde Objeto A —> Objeto B —> Objeto C —> … —> Objeto es el modelo básico de la cadena de prototipos

La última actualización del diagrama de relaciones:

202201241347628.jpg



Luego se han introducido todos los conocimientos teóricos sobre prototipo, [[Prototipo]], objeto prototipo y cadena de prototipos, hagamos un resumen:

  • Cada función tiene un atributo prototipo que apunta a su objeto prototipo.
  • El objeto prototipo de la función tiene un atributo de constructor, que apunta a su constructor, que es la función misma.
  • Cada objeto tiene un atributo [[Prototipo]], que apunta a su objeto prototipo
  • El objeto prototipo también puede apuntar a su objeto prototipo a través de [[Prototipo]], es decir, el prototipo del prototipo
  • Se forma una cadena de prototipos a través de cada objeto prototipo.

Supongo que te gusta

Origin blog.csdn.net/qq_52174675/article/details/122662884
Recomendado
Clasificación