En JavaScript, una función es un objeto de tipo Function
que contiene propiedades y métodos. El prototipo (Prototype)
es un atributo del objeto de tipo Function
.
El atributo prototype
se incluye cuando se define la función y su valor inicial es un objeto vacío. No hay ningún tipo de prototipo definido para funciones en JavaScript, por lo que el prototipo puede ser de cualquier tipo.
El prototipo se utiliza para guardar las propiedades y métodos compartidos del objeto . Las propiedades y métodos del prototipo no afectan las propiedades y métodos de la función en sí.
// Propiedades del tipo de función -> propiedades que tienen todas las funciones console.log(Function.prototype); //[Función] //Definir función function fn() { console.log('esta es la función'); } //El valor predeterminado del prototipo es el objeto vacío console.log(fn.prototype); //fn {} // La función contiene un constructor --> todos los tipos de referencia son en realidad constructores console.log(Number.prototype); //[Number: 0] console.log(Object.prototype);//{}
Puede obtener el prototipo del objeto de las dos formas siguientes para establecer propiedades y métodos compartidos:
prototype
del constructorgetPrototype
del método Objeto objeto (obj).función fn() { console.log('esta es la función'); } //Utiliza la estructura de sintaxis de atributos del objeto de acceso console.log(fn.prototype); //fn {} console.log(fn['prototipo']);//fn {} //El tipo de objeto proporciona el método getPrototypeOf() console.log(Object.getPrototypeOf(fn)); //[Función]
Object.getOwnPropertyDescriptors()
se utiliza para obtener los descriptores de todas las propiedades propias de un objeto.
var resultado = Object.getOwnPropertyDescriptor(Object.prototype,'constructor'); console.log(resultado) //Los resultados de salida son los siguientes: //{ // valor: [Función: Objeto], // escribible: verdadero, // enumerable: falso, // configurable: verdadero // }
constructor是在创建函数的时候自动添加的,指向构造函数本身
Puede configurar las propiedades y métodos del prototipo de las dos maneras siguientes:
Constructor.prototype.Attribute name = valor de atributo; Constructor.prototype.Method name = function(){};
Cuando necesitamos agregar muchos atributos al prototipo, es demasiado problemático escribir
构造函数.prototype.属性名
una y otra vez. Podemos modificar directamente todo elprototype
constructor.prototype = {. Nombre del atributo: valor del atributo, Nombre del método: function(){}}
function foo () {}foo.prototype = { constructor: foo, nombre: 'mermelada', edad: 18, dirección: 'Beijing'}var fn = new foo()console.log(fn.address) //Beijing
Cada objeto tendrá un método isPrototypeOf()
, que se utiliza para determinar si el objeto es un prototipo de otro objeto.
El código de muestra es el siguiente: // Definir el objeto mediante el inicializador var obj = { nombre:'mermelada' } //Definir la función constructora Hero() {} // Asigna el objeto obj al prototipo del constructor Hero Hero.prototype = obj; // Crea un objeto mediante el constructor var hero = new Hero(); // El método isPrototypeOf() determina si el objeto especificado es el prototipo de otro objeto var result = obj.isPrototypeOf(hero); console.log(result);//true
verifica que
obj
es el prototipohero
A continuación usamos un fragmento de código para ampliar nuestra comprensión de la cadena de prototipos:
Escenario : Encuentra los objetos en el objeto obj. Pasos realizados por el atributo de dirección js: 1. Se activará la operación de obtención. 2. Busque el atributo en el objeto actual 3. Si no se encuentra, buscará en el objeto de la cadena prototipo (__proto__) en este momento. Si no se encuentra, continuará buscando a lo largo de la cadena de prototipos hasta que se encuentre el prototipo de nivel superior (lo que es el prototipo de nivel superior no está claro temporalmente)
var obj = {. nombre: 'mermelada', edad: 19 } /* Requisito: busque el atributo de dirección en el objeto obj*/ // La cadena de prototipos se busca capa por capa. Si no se encuentra, se buscará hasta que se encuentre el prototipo de nivel superior obj.__proto__ = {}. obj.__proto__.__proto__ = {} obj.__proto__.__proto__.__proto__ = { dirección: 'Pekín' } console.log(obj.address) // Beijing console.log(obj.__proto__.__proto__.__proto__) // { dirección: 'Beijing' }
Finalmente encuentre el atributo de dirección.
那么这里有一个问题,如果一直没有查到,会无穷尽的去查找吗?接下来我们就来了解一下
Como mencionamos anteriormente, no buscaremos interminablemente a lo largo de la cadena de prototipos. Cuando se encuentre el prototipo de nivel superior, se devolverá undefined
si aún no se ha encontrado.
Entonces, ¿cuál es el prototipo de nivel superior?
El código de muestra es el siguiente:
var obj = { name: 'jam' }console.log(obj.__proto__) // {}console.log(obj.__proto__.__proto__) //
El prototipo del objeto literal nulo obj es:
{}
.{}
es el prototipo de nivel superior. Cuando continuamos imprimiendo__proto__
hacia arriba, se devuelve un valor nulo, lo que demuestra que la capa anterior ya es el prototipo de nivel superior.
La siguiente figura es un complemento del prototipo de nivel superior
.falta en el primer fragmento de código:
顶层原型就是Object.prototype
3.1 Entonces, ¿dónde está el final de la cadena de prototipos? Por ejemplo, ¿el tercer objeto también tiene un atributo prototipo __proto__
?
var obj = {nombre:'jam'}obj.__proto__ = {}obj.__proto__.__proto__ = {}obj.__proto__.__proto__.__proto__ = {}console.log(obj.__proto__.__proto__.__proto__.__proto__) // {}
Descubrimos que el resultado impreso anterior es空对象{}
var obj = { nombre: 'mermelada', edad: 19 } console.log(obj.__proto__) // {} console.log(Objeto.prototipo) // {} console.log(obj.__proto__ === Object.prototype) // true
El objeto es la clase principal de todas las clases, por lo que obj.__proto__ es en realidad Object.prototype,
console.log(obj.__proto__ === Object.prototype) // true
podemos ver que el resultado Object.prototype es el prototipo de nivel superior
{}
3.2 Entonces podemos preguntar. : {}
¿Hay algo especial en los prototipos?
console.log(obj.__proto__.__proto__.__proto__.__proto__.__proto__) // null;
Object.prototype
es un objeto vacío {}, no está vacío, pero las propiedades dentro no son enumerables. Por ejemplo, imprimamos constructor
. propiedad para ver <!-- Se puede ver que hay un atributo de constructor y no está vacío -->console.log(Object.prototype.constructor) // [Función: Objeto] <!-- el constructor hace referencia a Objeto -->
Object.prototype
a través del método Object.getOwnPropertyDescriptors()
. console.log(Object.getOwnPropertyDescriptors(Object.prototype)) //Como se muestra en la captura de pantalla larga a continuación