La cadena prototipo es un poco confusa de entender, y hay mucha información en línea. Cada vez que no puedo dormir por la noche, siempre me gusta encontrar algunos artículos prototipo de cadenas y cierres en línea para leer, lo cual es muy efectivo.
No te preocupes por esos muchos términos, realmente no te ayudará, excepto hacer que tu cerebro se torciera. Solo mire la cadena prototipo de manera simple y brusca, y piense en cosas que no tienen nada que ver con el código, como humanos, demonios y hombres transexuales.
1) Las personas nacen por seres humanos, y los monstruos nacen por demonios. Los humanos y los demonios son ambos casos de objetos, mientras que los humanos y los demonios son prototipos. Un prototipo también es un objeto, llamado objeto prototipo.
2) La madre de una persona y su padre pueden dar a luz a un grupo de bebés, y una madre demonio y su padre pueden dar a luz a un grupo de bebés. La esposa de un hombre y un hombre pueden dar a luz a un grupo de bebés. Un hombre es un constructor, comúnmente conocido como hombre.
3) Las personas pueden registrar información sobre el sexo, para que las personas puedan encontrar información sobre el sexo a través del sexo, es decir, pueden encontrar el constructor a través de objetos prototipo.
4) Las personas pueden dar a luz a muchos bebés en sus madres, pero estos bebés solo tienen una madre, que es la singularidad del prototipo.
5) Las personas también nacen por personas, encuentran personas a través de las personas y luego encuentran personas a través de las personas ... Esta relación se llama cadena prototipo.
6) La cadena prototipo no es infinita. Cuando sigues mirando a través de las personas, encontrarás que la gente está jodiendo ... no son jodidos humanos, es decir, la cadena prototipo finalmente apunta a NULL.
7) Las personas nacidas con una madre se parecerán a personas, y los monstruos nacidos con una madre serán feas. Esto se llama herencia.
8) Heredó el color de la piel de su madre, su madre heredó el color de la piel de su madre, su madre ..., esta es la herencia de la cadena prototipo.
9) Si no tiene un hogar, su hogar se refiere a la casa de su madre; Si su madre no tiene un hogar, entonces su hogar se refiere a la casa de su madre ... esta es la búsqueda ascendente de la cadena prototipo.
10) heredará la apariencia de su madre, pero también puede teñir su cabello, champú, cortar y soplar, es decir, los atributos del objeto pueden personalizarse y anular los atributos heredados.
11) Aunque has lavado, cortado, soplado y teñido cabello amarillo, no puedes cambiar la apariencia de tu madre. El hermano y la hermana menores nacidos de tu madre no tienen nada que ver con tu cabello amarillo, cortado y el cabello amarillo soplado, es decir, la instancia del objeto no puede cambiar las propiedades del prototipo.
12) Pero si su casa es quemada por usted, significa que su madre y sus hermanos están quemados, y este es el intercambio de atributos prototipo.
13) El apodo de tu madre es Azhen, y la tía de su vecina te llama Azhener, pero después de que el cabello de tu madre pasó de Piaorou al Rey Golden Lion, la tía de al lado cambió sus palabras y te llamó el Príncipe Golden Lion. Esto se llama la naturaleza dinámica del prototipo.
14) Su madre ama la belleza y fue a Corea para una cirugía plástica. Ni siquiera podía reconocer a su madre. Incluso si el cabello de tu madre volvió a la suavidad, el vecino de al lado todavía te llamaba el príncipe del león dorado. Debido a que nadie reconoció a su madre, su madre ha regresado a la fábrica después de la cirugía plástica. Esta es la reescritura general del prototipo.
¡Maldita sea! ¡Eres suficiente! ¡No bb! ¡Muéstrame el código!
Función Persona (nombre) {this.name = name; } function Mother () {} Mother.Prototype = {// Madre's Prototype Age: 18, Home: ['Beijing', 'Shanghai']}; Person.prototype = new Mother (); // El prototipo de la persona es madre // Use la herramienta de depuración Chrome para ver el prototipo, proporcionando la interfaz __proto__ para ver el prototipo var p1 = nueva persona ('jack'); // P1: 'Jack'; __proto __: 18, ['beijing', 'shanghai'] var p2 = nueva persona ('marca'); // P2: 'Mark'; __proto __: 18, ['Beijing', 'Shanghai'] p1.age = 20; /* La instancia no puede cambiar el atributo de valor básico del prototipo, al igual que lave, corta, sopla y teñir el cabello amarillo no tiene nada que ver con su madre* La operación ordinaria de agregar un atributo de edad bajo la instancia P1 no tiene nada que ver con el prototipo. Igual que var o {}; O.AGE = 20. * P1: Hay una edad de atributo adicional a continuación, y __proto__ es lo mismo que la madre. Prototipo, edad = 18. * p2: solo el nombre del atributo, __proto__ es el mismo que la madre.prototype*/p1.home [0] = 'shenzhen'; /* Compartir atributos de tipo de referencia en el prototipo es como quemas tu hogar, está quemando el hogar de toda tu familia* Esto es un poco pase, ¿hagamos que lo hagamos cuidadosamente a continuación? * P1: 'Jack', 20; __proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 18, ['Shenzhen', 'Shanghai']*/p1.home = ['Hangzhou', 'Guangzhou']; /* De hecho, la misma operación que p1.age = 20. Cambiar a esta comprensión: var o {}; O.house = ['Big', 'House']* P1: 'Jack', 20, ['Hangzhou', 'Guangzhou']; __proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 18, ['shenzhen', 'shanghai']*/delete p1.age; /* Después de eliminar los atributos personalizados, el valor del prototipo sobrescribido originalmente será reemplazada. Este es el mecanismo de búsqueda ascendente, por lo que existe la siguiente dinámica* P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 18, ['shenzhen', 'shanghai']*/persona.prototype.lastname = 'jin'; /* Reescribir el prototipo y reaccionar dinámicamente a la instancia. Así como su madre se ha convertido en una persona moderna, los vecinos dicen que usted es el hijo de una mujer moderna cuando lo mencionan* Tenga en cuenta que estamos reescribiendo el prototipo de la persona aquí, que es agregar un atributo de último nombre a la madre, que es equivalente a la madre.lastname = 'jin'* esto no es cambiar la madre. Prototipo. Si cambia diferentes niveles, los efectos a menudo serán muy diferentes. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']*/persona.prototype = {edad: 28, dirección: {país: 'usa', ciudad: 'washington'}}; var p3 = nueva persona ('obama'); /* Reescribe el prototipo! En este momento, el prototipo de la persona se había convertido por completo en un objeto nuevo, lo que significa que esa persona había cambiado a su madre. * Para entenderlo así: var a = 10; b = a; a = 20; c = a. Entonces B permanece sin cambios y se convierte en C, por lo que P3 cambia y no tiene nada que ver con la madre. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai']* P2: 'Mark'; __proto __: 'jin'; __ proto __: 18, ['shenzhen', 'shanghai']* p3: 'obama'; __ proto__: 28 {country: 'USA', City: 'Washington'}*/Mother.prototype.no = 9527;/* Reescribir el prototipo del prototipo y la dinamicalmente del caso. Así como su madre se ha convertido en una nueva tendencia, los vecinos dicen que realmente eres una abuela moderada* Tenga en cuenta que estamos reescribiendo la madre. Prototipo aquí, P1P2 cambiará, pero el P3 anterior no tiene nada que ver con la madre, y no lo afectará. * P1: 'Jack', ['Hangzhou', 'Guangzhou']; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai'], 9527* P2: 'Mark'; __proto __: 'Jin'; __ Proto __: 18, ['Shenzhen', 'Shanghai'], 9527* P3: 'Obama'; __proto__: 28 {país: 'EE. UU.', Ciudad: 'Washington'}*/Mother.ProTotype = {Car: 2, Hobby: ['Run', 'Walk']}; var p4 = nueva persona ('Tony');/* Reescribe el prototipo del prototipo! ¡En este momento, el prototipo de la madre se ha convertido por completo en un objeto nuevo! * Dado que la persona y la madre han sido desconectadas de arriba, el cambio de la madre ya no afectará a la persona. * P4: 'Tony'; __ Proto__: 28 {país: 'EE. UU.', Ciudad: 'Washington'}*/persona.prototype = new Mother (); // Bind Var nuevamente p5 = nueva persona ('luffy'); // Si necesita aplicar estos cambios en este momento, debe volver a atacar el prototipo de la persona a la madre // p5: 'luffy'; __ proto__: 2, ['ejecutar', 'walk'] p1 .__ proto __.__ protopo __.__ protopo __.__ proto__ // null, ¿piensas el punto final? Madre .__ Proto __.__ Proto __.__ Proto__ // nulo, ¿crees que el punto final de la cadena prototipo no es nulo?Básicamente puedes entender después de leerlo?
Ahora hablemos de la diferencia entre p1.age = 20, p1.home = ['hangzhou', 'guangzhou'] y p1.home [0] = 'shenzhen'. p1.home [0] = 'shenzhen'; En resumen, es una forma como p1.object.method, p1.object.property.
p1.age = 20; p1.home = ['Hangzhou', 'Guangzhou']; Estas dos oraciones son fáciles de entender. Olvida el prototipo primero y piense en cómo agregamos atributos a un objeto ordinario:
var obj = new Object (); obj.name = 'xxx'; obj.num = [100, 200];
¿Entiendes de esta manera? Es lo mismo.
Entonces, ¿por qué P1.Home [0] = 'shenzhen' crea una propiedad de matriz de inicio bajo P1 y luego establece su primera posición en 'shenzhen'? Olvidemos esto primero, piense en el objeto OBJ anterior. Si se escribe así: var obj.name = 'xxx', obj.num = [100, 200], ¿puede obtener el resultado que desea? Obviamente, no obtendrá nada excepto un error. Debido a que OBJ aún no se ha definido, ¿cómo puedes agregarle algo? Del mismo modo, el hogar en P1. Home [0] no está definido en P1, por lo que es imposible definir directamente el hogar [0]. Si desea crear una matriz de inicio bajo P1, por supuesto, está escrita así:
p1.home = []; p1.home [0] = 'shenzhen';
¿No es este el método más utilizado?
La razón por la cual p1.home [0] = 'shenzhen' no informa directamente un error es porque hay un mecanismo de búsqueda en la cadena prototipo. Cuando ingresamos P1.Object, el mecanismo de búsqueda de la cadena prototipo es buscar el valor correspondiente en la instancia primero. Si no se puede encontrar, se buscará en el prototipo. Si no se puede encontrar, buscará en el nivel anterior de la cadena prototipo ... alcanzará el final de la cadena prototipo, es decir, si aún no se ha encontrado, devolverá un indefinado. Cuando entramos en p1.home [0], el mismo mecanismo de búsqueda también es cierto. Primero busque P1 para ver si hay algún atributo y método llamado Home, y luego busque hacia arriba paso a paso. Finalmente lo encontramos en el prototipo de la madre, por lo que modificarlo es equivalente a modificar el prototipo de la madre.
En resumen: p1.home [0] = 'shenzhen' es equivalente a la madre.prototype.home [0] = 'shenzhen'.
Del análisis anterior, podemos ver que el principal problema de la herencia de la cadena prototipo radica en el intercambio de atributos. Muchas veces solo queremos compartir métodos pero no atributos. Idealmente, cada instancia debe tener atributos independientes. Por lo tanto, hay dos formas de mejorar la herencia prototipo:
1) Herencia de combinación
función Mother (Age) {this.age = Age; this.hobby = ['Running', 'Football']} Mother.prototype.showage = function () {console.log (this.age); }; función de la función (nombre, edad) {madre.call (this, edad); // Segunda ejecución this.name = name; } Persona.prototype = new Mother (); // Primera ejecución persona.prototype.constructor = persona; persona.prototype.showname = function () {console.log (this.name);} var p1 = nueva persona ('Jack', 20); p1.hobby.push ('baloncesto'); // P1: 'Jack'; __proto __: 20, ['Running', 'Football'] var p2 = nueva persona ('marca', 18); // P2: 'Mark'; __proto __: 18, ['correr', 'fútbol']El resultado es morado:
Cuando se realiza la primera ejecución aquí, obtienes Person.Prototype.age = Undefined, Person.Prototype.hobby = ['Running', 'Football']. La segunda ejecución es que var p1 = nueva persona ('jack', 20) y obtienes p1.age = 20, p1.hobby = ['corriendo', 'fútbol']. Después de empujar, se convierte en p1.hobby = ['correr', 'fútbol', 'baloncesto']. De hecho, es relativamente simple comprender los cambios de esto. Puede obtener este resultado simplemente reemplazando esto. Si siente que es un poco confuso entender, trate de tirar los conceptos en su mente y ejecute el código de arriba a abajo como navegador. ¿Saldrá?
Al ejecutar el prototipo de constructor Madre () por segunda vez, copiamos una copia de las propiedades del prototipo en la instancia del objeto, para que podamos separarnos y separarnos de las propiedades del prototipo. Si tiene cuidado, encontrará que la primera vez que llamamos a Madre (), parece que no tiene ningún uso. ¿Cómo no podemos llamarlo? Sí, existe la siguiente herencia de combinación parasitaria.
2) Herencia de combinación parasitaria
Function Object (o) {function f () {} f.prototype = o; return new f ();} function hereitprototype (persona, madre) {var prototype = object (Mother.prototype); prototipo.constructor = persona; Persona.prototype = prototipo; } función Madre (edad) {this.age = edad; this.hobby = ['Running', 'Football']} Mother.prototype.showage = function () {console.log (this.age); }; función de la función (nombre, edad) {madre.call (this, edad); this.name = name; } HerheritPrototype (persona, madre); Persona.prototype.showname = function () {console.log (this.name);} var p1 = nueva persona ('Jack', 20); p1.hobby.push ('baloncesto'); // p1: 'jack'; __proto __: 20, ['Running', 'Football'] var p2 = nueva persona ('marca', 18); // P2: 'Mark'; __proto __: 18, ['correr', 'fútbol']El resultado es morado:
Ya no hay atributos de edad y pasatiempo en el prototipo, ¡solo hay dos métodos, que son exactamente el resultado que queremos!
El punto clave está en el objeto (o), donde un objeto temporal se toma prestado aquí para evitar inteligentemente llamar a la nueva madre (), y luego devolver una nueva instancia de objeto con el prototipo O, completando así la configuración de la cadena prototipo. Es muy confuso, ¿verdad? Eso se debe a que no podemos establecer persona.prototype = Mother.prototype directamente.
resumen
---------------------------------------------------------------------------------------------------
Habiendo dicho tanto, en realidad solo hay un núcleo: intercambio de atributos y control independiente. Cuando su instancia de objeto necesita atributos independientes, la esencia de todas las prácticas es crear atributos en la instancia de objeto. Si no piensa demasiado, puede definir directamente los atributos independientes que necesita en persona para sobrescribir las propiedades del prototipo. En resumen, al usar la herencia prototipo, debe prestar especial atención a los atributos en el prototipo, porque todas son existencias que afectan a todo el cuerpo.
A continuación se muestra una lista simple de varios métodos para crear objetos en JS. El método más utilizado ahora es el modo de combinación. Los estudiantes familiares pueden saltar hasta el final del artículo y les gusta.
1) Modo original
// 1. Modo original, objeto Modo literal var persona = {nombre: 'Jack', edad: 18, sayname: function () {alert (this.name); }}; // 1. Modo original, modo de constructor de objeto var persona = nuevo objeto (); persona.name = 'Jack'; persona. persona.sayname = function () {alert (this.name);};Obviamente, cuando queremos crear lotes de persona1, persona2 ..., tenemos que escribir mucho código cada vez, ¡e incluso los copypasters senior no pueden soportarlo! Luego hay un modelo de fábrica de producción en masa.
2) Modelo de fábrica
// 2. Modo de fábrica, defina una función para crear la función de objeto Createperson (nombre, edad) {var temp = new Object (); persona.name = name; persona.age = edad; persona.sayname = function () {alert (this.name);}; return temp; }El modo de fábrica es la producción en masa, y puede ingresar al modo de fabricación de hombres con una llamada simple (Papapapa ...). Puede crear un montón de bebés especificando su nombre y edad, y liberar sus manos. Sin embargo, dado que se opera en una fábrica, no puede identificar qué tipo de objeto es, ya sea un humano o un perro (la instancia de la prueba es objeto). Además, cada vez que crea un humano, debe crear un objeto temporal independiente, el código está hinchado y la mariposa es elegante.
3) Constructor
// 3. Modo de constructor, defina una función de constructor para la persona de la función de objeto (nombre, edad) {this.name = name; this.age = age; this.sayname = function () {alert (this.name);}; } var p1 = nueva persona ('Jack', 18); // crear una persona de objeto P1 ('Jack', 18); // Los métodos de atributo se dan al objeto de la ventana, window.name = 'jack', window.sayname () emitirá JackEl constructor es similar a los constructores de clases en C ++ y Java, y es fácil de entender. Además, la persona se puede usar como reconocimiento de tipo (instancia de prueba es persona y objeto). Sin embargo, todas las instancias siguen siendo independientes, y los métodos de diferentes instancias son en realidad diferentes funciones. Olvidé la función de la palabra aquí, solo trate a SayName como un objeto y entiéndalo. Es decir, el nombre de dicho de Zhang San y el nombre de Say de Li Si tienen existencias diferentes, pero obviamente lo que esperamos es compartir un nombre de dicho para salvar la memoria.
4) Modo prototipo
// 4. Modo prototipo, defina directamente la función de la función de atributo prototipo () {} persona.prototype.name = 'jack'; persona.prototype.age = 18; persona.prototype.sayname = function () {alert (this.name); }; // 4. Prototype, definición literal del método de la función de la persona () {} persona.prototype = {name: 'Jack', edad: 18, sayname: function () {alert (this.name); }}; var p1 = nueva persona (); // name = 'jack'var p2 = new Person (); // nombre = 'Jack'Lo que debe tenerse en cuenta aquí es compartir atributos y métodos prototipos, es decir, todas las instancias solo se refieren a los métodos de atributo en el prototipo, y los cambios generados en cualquier lugar causarán cambios en otras instancias.
5) Modo mixto (construcción + prototipo)
// 5. Modo de combinación de construcción prototipo, función de función (nombre, edad) {this.name = name; this.age = age;} persona.prototype = {hobby: ['running', 'football']; sayname: function () {alerta (this.name); }, sayage: function () {alert (this.age); }}; var p1 = nueva persona ('Jack', 20); // P1: 'Jack', 20; __proto__: ['correr', 'fútbol'], sayname, sayagevar p2 = nueva persona ('marca', 18); // P1: 'Mark', 18; __ Proto__: ['Running', 'Football'], Sayname, SayageEl enfoque es poner los métodos de propiedad que deben ser independientes en el constructor, y las partes que se pueden compartir se colocan en el prototipo. Esto puede maximizar los ahorros de memoria al tiempo que conserva la independencia de las instancias de objetos.