Hay muchas relaciones caóticas en JavaScript. La cadena de alcance es una relación de cadena unidireccional, que es bastante simple y clara; La relación de llamada de este mecanismo es un poco complicada; y en cuanto al prototipo, es una relación triangular entre prototipo, proto y constructor. Este artículo primero usa una imagen para aclarar el significado, y luego explica la relación triangular del prototipo en detalle.
Ilustración
concepto
La compleja relación en la imagen de arriba en realidad proviene de dos líneas de código.
función foo () {}; var f1 = new foo;【Constructor】
La función utilizada para inicializar el objeto recién creado es el constructor. En el ejemplo, la función foo () es un constructor
【Objeto de instancia】
El objeto creado por la nueva operación del constructor es un objeto de instancia. Puede usar un constructor para construir múltiples objetos de instancia
función foo () {}; var f1 = new foo; var f2 = new foo; console.log (f1 === f2); // falso【Prototipo de objetos y prototipo】
El constructor tiene una propiedad prototipo que apunta al objeto prototipo del objeto de instancia. Múltiples objetos instanciados por el mismo constructor tienen el mismo objeto prototipo. Utilice regularmente objetos prototipo para lograr la herencia
función foo () {}; foo.prototype.a = 1; var f1 = new foo; var f2 = new foo; console.log (foo.prototype.a); // 1console.log (f1.a); // 1console.log (f2.a); // 1console.log (f2.a); // 1 1【constructor】
El objeto prototipo tiene un atributo de constructor que apunta a la función de constructor correspondiente al objeto prototipo.
función foo () {}; console.log (foo.prototype.constructor === foo); // trueDado que el objeto de instancia puede heredar las propiedades del objeto prototipo, el objeto de instancia también tiene el atributo de constructor, que también señala la función de constructor correspondiente al objeto prototipo.
función foo () {}; var f1 = new foo; console.log (f1.constructor === foo); // true【Proto】
El objeto de instancia tiene un atributo Proto que apunta al objeto prototipo correspondiente al objeto de instancia
función foo () {}; var f1 = new foo; console.log (f1 .__ proto__ === foo.prototype); // trueilustrar
Se ha introducido el concepto, y ahora explicaremos la relación en detalle.
función foo () {}; var f1 = new foo;【Parte 1: Foo】
El objeto de instancia F1 es creado por la nueva operación del constructor foo (). El objeto prototipo del constructor foo () es foo.prototype; El objeto de instancia F1 también apunta al objeto prototipo foo.prototype a través del atributo __proto__.
función foo () {}; var f1 = new foo; console.log (f1 .__ proto === foo.prototype); // trueEl objeto de instancia F1 en sí no tiene un atributo de constructor, pero puede heredar el atributo de constructor del objeto prototipo foo.prototype.
función foo () {}; var f1 = new foo; console.log (foo.prototype.constructor === foo); // trueConsole.log (f1.constructor === foo); // trueconsole.log (f1.hasownproperty ('constructor')); //La siguiente figura muestra el efecto de la consola del objeto de instancia F1
【Parte 2: Objeto】
Foo.prototype es el objeto prototipo de F1, y también es un objeto de instancia. De hecho, cualquier objeto puede considerarse como un objeto instanciado a través de la nueva operación del constructor Object (). Entonces, foo.prototype es un objeto de instancia, su constructor es objeto () y el objeto prototipo es objeto.prototype. En consecuencia, la propiedad prototipo del objeto constructor () apunta al objeto prototipo del objeto; La propiedad Proto del objeto de instancia foo.prototype también apunta al objeto prototipo del objeto
función foo () {}; var f1 = new foo; console.log (foo.prototype .__ proto__ === objeto.prototype); // trueEl objeto de instancia foo.prototype en sí tiene el atributo del constructor, por lo que anula el atributo del constructor heredado del objeto prototipo de objeto.prototype
función foo () {}; var f1 = new foo; console.log (foo.prototype.constructor === foo); // trueConsole.log (objeto.prototype.constructor ==== Objeto); // trueConsole.log (foo.protype.hasownproperty ('constructor')); // trueConsole.log (foo.prototype.hasownproperty ('constructor')); // trueLa siguiente figura muestra el efecto de la consola del objeto de instancia foo.prototype
Si Object.prototype es un objeto de instancia, ¿cuál es su objeto prototipo? El resultado es nulo. Creo que este también puede ser el resultado de TypeOf Null, que es una de las razones por las cuales 'Objeto'
console.log (objeto.prototype .__ proto__ === null); // verdadero
【Parte 3: función】
Como se mencionó anteriormente, las funciones son objetos, pero objetos con funciones especiales. Cualquier función puede considerarse como el resultado de la instanciación a través de la nueva operación del constructor de funciones ().
Si la función foo se considera un objeto de instancia, su constructor es function () y su objeto prototipo es funct.prototype; Del mismo modo, el constructor del objeto de función también es function (), y su objeto prototipo es funct.prototype.
función foo () {}; var f1 = new foo; console.log (foo .__ proto__ === function.prototype); // trueConsole.log (objeto .__ proto__ === function.prototype); // trueEl atributo de constructor de la función de objeto prototipo.prototype apunta a la función de constructor (); El objeto de instancia del objeto y el foo no tienen el atributo del constructor, y es necesario heredar el atributo de constructor de la función de objeto prototipo.prototype.
function foo () {}; var f1 = new foo; console.log (function.prototype.constructor === function); // trueConsole.log (foo.constructor === function); // trueConsole.log (foo.hasownprepertypreperty ('constructor')); // falseconsole.log (objetivo ==. Función); // trueConsole.log (object.hasownproperty ('constructor')); // falsoTodas las funciones pueden considerarse como objetos instanciados de la nueva operación de la función Constructor (). Entonces, la función puede considerarse como el resultado de llamar a su propia nueva instancia de operación.
Entonces, si la función es un objeto de instancia, su constructor es función, y su objeto prototipo es funct.prototype
console.log (function .__ proto__ === function.prototype); // trueConsole.log (function.prototype.constructor === function); // trueconsole.log (function.prototype === function); // trueconsole.log (function.prototype === function); // true
If function.prototype es un objeto de instancia, ¿cuál es su objeto prototipo? Como antes, todos los objetos pueden considerarse como el resultado de la instancia de la nueva operación del constructor Object (). Por lo tanto, el objeto prototipo de function.prototype es objeto.prototype, y su función prototipo es objeto ()
console.log (function.prototype .__ proto__ === objeto.prototype); // verdadero
La segunda parte presenta que el objeto prototipo de objeto.prototype es nulo
console.log (objeto.prototype .__ proto__ === null); // verdadero
Resumir
【1】 La función (la función también es una función) es el resultado de una nueva función, por lo que la función se puede usar como un objeto de instancia, su constructor es function () y el objeto prototipo es function.prototype
【2】 Los objetos (las funciones también son objetos) son el resultado del nuevo objeto, por lo que el objeto se puede usar como un objeto de instancia, su constructor es objeto () y el objeto prototipo es objeto.prototype
【3】 objeto. El objeto prototipo del propototipo es nulo