Al crear objetos a través de constructores de objetos u literales de objetos, al crear muchos objetos con la misma interfaz, se generará una gran cantidad de código duplicado. Por simplicidad, se introdujo el modelo de fábrica.
Modelo de fábrica
function createperson (nombre, edad, trabajo) {var obj = new Object (); obj.name = nombre; obj.age = edad; obj.job = trabajo; obj.sayhello () {alert (this.name); }; return obj;} var p1 = createperson ("xxyh", 19, "programador"); var p2 = createperson ("zhangsan", 18, "estudiante");Esta forma de crear objetos simplifica enormemente el código, pero también hay una deficiencia, es decir, el tipo de objeto no se puede determinar. Para resolver este problema, aparece el siguiente patrón.
Modo de constructor
Cree un constructor personalizado para definir propiedades y métodos de tipos de objetos personalizados.
Función persona (nombre, edad, trabajo) {this.name = name; this.age = edad; this.job = trabajo; this.sayName = function () {alert (this.name); };} var p1 = nueva persona ("xxyh", 19, "programador"); var p2 = nueva persona ("Jack", 18, "estudiante");En el ejemplo anterior, Person () reemplaza a Createperson (). Además, hay varias diferencias:
• Crear objetos sin pantalla;
• Asigne directamente atributos y métodos a este objeto
• Sin declaración de retorno
Para crear un objeto de persona, debe usar el nuevo operador. Se divide en 4 pasos:
• Crear un nuevo objeto
• Asigne el alcance del constructor a un nuevo objeto
• Ejecutar el código en el constructor
• Devolver nuevo objeto
P1 y P2, respectivamente, guardan una instancia de persona.
alerta (p1.constructor == persona); // TRUEALERT (P2.Constructor == Persona); // verdadero
Es mejor usar instancia al detectar tipos:
alerta (instancia p1 de objeto); // TRUEALERT (instancia p1 de persona); // TRUEALERT (P2 Instance de objeto); // TRUEALERT (instancia p2 de persona); // TRUEALERT (instancia p2 de persona); // verdadero
P1 y P2 son instancias de objetos, porque todos los objetos se heredan de Object.
2.1 Trate a los constructores como funciones
// use var persona = nueva persona ("xxyh", 19, "programador"); persona.sayname (); // "xxyh" // use como una persona de función normal ("zhangsan", 18, "estudiante"); // Agregar a WindowWindow.sayName (); // "zhangsan" // llamar a var obj en el alcance de otro objeto obj = nuevo objeto (); Person.call (obj, "Jack", 29, "Gerente"); obj.sayName (); // "Jack", OBJ tiene todas las propiedades y métodos2.2 Problema de constructor
El problema con el uso de constructores es que cada método debe recrearse en cada instancia. P1 y P2 tienen un método SayName (), pero no son una instancia de función. En JavaScript, una función es un objeto, por lo que cada vez que se define una función, se instancia un objeto.
El constructor también se puede definir así:
Función persona (nombre, edad, trabajo) {this.name = name; this.age = edad; this.job = trabajo; this.sayName = new function ("alerta (this.name)");}Por lo tanto, las funciones del mismo nombre en diferentes instancias no son iguales:
alerta (p1.sayname == P2.SayName); // FALSO
Sin embargo, crear dos funciones con la misma función es redundante, y no es necesario unir la función a un objeto específico antes de ejecutar el código.
Función persona (nombre, edad, trabajo) {this.name = name; this.age = edad; this.job = trabajo; this.sayname = sayname;} function saysname () {alert (this.name);} var p1 = nueva persona ("xxyh", 19, "programador"); var p2 = nueva persona ("Jack", 18, "estudiante");Lo anterior mueve la definición de sayname () fuera del constructor, y luego establece el atributo SaysName como la función de nombre de nombre global dentro del constructor. De esta manera, SayName contiene un puntero a la función, y P1 y P2 comparten la misma función SayName () definida en el alcance global.
Sin embargo, hay un nuevo problema con esto: las funciones definidas en el alcance global solo pueden ser llamados por cierto objeto. Y si el objeto define muchos métodos, el tipo de referencia pierde su encapsulación.
Modo de cadena prototipo
Cada función tiene una propiedad prototipo, que es un puntero que apunta a un objeto. El propósito de este objeto es incluir propiedades y métodos que pueden compartir por todas las instancias de un tipo específico . Prototype es el objeto prototipo de esa instancia de objeto creada al llamar al constructor. La ventaja de usar un objeto prototipo es que todas las instancias de objetos pueden compartir las propiedades y métodos que contiene. Esto significa que en lugar de definir la información de la instancia de objeto en el constructor, esta información se agrega al objeto prototipo.
función persona () {} persona.prototype.name = "xxyh"; persona.prototype.age = 19; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona1 = nueva persona (); persona1.sayname (); // "xxyh" var persona2 = nueva persona (); persona2.sayname (); // alerta "xxyh" (persona1.sayname == persona2.sayname); // verdadero3.1 Comprender objetos prototipo
Simplemente cree una nueva función, se creará una propiedad prototipo para la función, que apunta al objeto prototipo de la función. Por defecto, todos los objetos prototipo obtendrán automáticamente una propiedad de constructor. Esta propiedad contiene un puntero a la función donde se encuentra la propiedad prototipo. Persona.prototype.constructor señala a la persona.
Cuando se llama al constructor para crear una instancia, el interior de la instancia contendrá un puntero (propiedad interna) al objeto prototipo del constructor, llamado [prototipo]]. Accedido a través de _proto en Firefox, Safari y Chrome. Esta conexión existe entre la instancia y el objeto prototipo del constructor, no entre la instancia y el constructor.
La siguiente figura muestra la relación entre cada objeto:
Person.prototype señala el objeto prototipo y persona.prototype.constructor señala a la persona. Además del atributo del constructor, hay otros atributos agregados en el prototipo. Todas las instancias de la persona contienen una propiedad interna que solo apunta a la persona. Prototipo, y no tienen una relación directa con el constructor.
Aunque no se puede acceder [[prototipo]], el método ISPrototypeOf () se puede usar para determinar si existe tal relación entre los objetos.
alerta (persona.prototype.isprototypeOf (persona1)); // TRUEALERT (Person.Prototype.IsprototypeOf (Person2)); // verdadero
Al leer las propiedades de un objeto, se realiza una búsqueda, con el objetivo del atributo con el nombre de pila. La búsqueda comienza con la instancia del objeto en sí. La búsqueda comienza desde la instancia del objeto en sí. Si se encuentra un atributo con el nombre de pila en la instancia, se devuelve el valor del atributo; Si no se encuentra, continúe buscando el objeto prototipo señalado por el puntero y busque el atributo con el nombre de determinación en el objeto prototipo. Si esta propiedad se encuentra en el objeto prototipo, se devuelve el valor de la propiedad.
Se puede acceder a los valores guardados en el prototipo a través de la instancia del objeto, pero los valores almacenados en el prototipo no se pueden reescribir a través de la instancia del objeto . Si agrega un atributo a la instancia con el mismo nombre que un atributo en el prototipo de instancia, el atributo bloqueará el atributo en el prototipo.
function Person () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona1 = nueva persona (); var persona2 = nueva persona (); persona1.name) "oooo"; alerta (persona1.name); // alerta "oooo" (persona2.name); // "xxyh"En el ejemplo anterior, el atributo de nombre en Person1 bloquea el atributo de nombre en el prototipo.
Cuando se agrega un atributo a una instancia de objeto, este atributo bloqueará los atributos del mismo nombre guardado en el objeto prototipo. Esto significa que la existencia de esta propiedad evitará el acceso a esa propiedad en el prototipo. Use Eliminar para eliminar las propiedades de instancia.
function Person () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona1 = nueva persona (); var persona2 = nueva persona (); persona1.name) "oooo"; alerta (persona1.name); // alerta "oooo" (persona2.name); // "xxyh" eliminar persona1.name; alert (persona1.name); // "xxyh"ASOWNProperty () puede detectar si existe una propiedad en una instancia o en un prototipo.
función persona () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona1 = nueva persona (); var persona2 = nueva persona (); alerta (alerta (persona1.hasewner "); // falseperson1.name = "oooo"; alert (persona1.hasownproperty ("nombre")); // verdaderoLa siguiente figura muestra la relación entre implementación y prototipo en diferentes situaciones:
3.2 Prototipo y en operador
Cómo usar el operador en el operador: úselo solo, en un bucle for-in. Cuando se usa solo, el operador in devuelve verdadero al acceder a una propiedad dada a través del objeto , si existe en la instancia o en el prototipo.
function Person () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona1 = nueva persona (); alerta ("name" en persona1); // trueperson1.name = "oooo"; alerta ("nombre" en persona1); // verdaderoCombinado con la característica anterior de AutownProperty (), se puede determinar que una propiedad es una propiedad en el prototipo o una propiedad en la instancia. Si el operador en el operador devuelve verdadero y haownproperty devuelve falso, la propiedad es una propiedad en el prototipo.
función HasPrototyPeProperty (objeto, nombre) {return! Object.hasownproperty (name) && (nombre en el objeto);}A continuación, echemos un vistazo al uso de HasPrototyPeProperty ():
function Person () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var persona = nueva persona (); alerta (alerta (haprototypePreperty (persona, "nombre");); // trueperson.name = "oooo"; alerta (hasprototypeproperty (persona, "nombre")); // FALSOAl usar el bucle for-in, todas las propiedades enumerables a las que se puede acceder a través del objeto, incluidas las propiedades en la instancia y las propiedades en el prototipo. Los atributos de instancia que bloquean los datos unenumerables en el prototipo (es decir, los atributos marcados como falsos por [[enumerables]]) también se devolverán en For-In, porque según las regulaciones, todos los atributos definidos por los desarrolladores son enumerables.
Para obtener todas las propiedades de instancia enumerables en un objeto, puede usar el método Object.Keys ().
función persona () {} persona.prototype.name = "xxyh"; persona.prototype.age = "20"; persona.prototype.job = "programador"; persona.prototype.sayname = function () {alert (this.name);}; var keys = object.keys (persona.prototype); alerta (keys); // nombre, edad, trabajo, saynameVar p1 = new Person (); p1.name = "oooo"; p1.age = 15; var p1_keys = object.keys (p1); alerta (p1_keys); // Nombre, edadSi necesita obtener todas las propiedades de instancias, puede usar el método Object.getOwnPropertynames ()
var keys = object.getOwnPropertynames (persona.prototype); alerta (claves); // "Constructor, nombre, edad, trabajo, nombre"
3.3 Sintaxis de prototipo más simple
Para agilizar la entrada, anule el objeto prototipo integrado con un objeto literal que contiene todas las propiedades y métodos.
función persona () {} persona.prototype = {nombre: "xxyh", edad: 18, trabajo: "programador", sayname: function () {alert (this.name); }};El anterior establece la persona. Prototipo para igualar un nuevo objeto creado en forma literal de objetos. El resultado es el mismo, pero el atributo del constructor ya no apunta a la persona.
El resultado correcto se puede devolver a través de instancia, pero el constructor no puede determinar el tipo de objeto:
var boy = new Person (); alerta (instancia de niño de objeto); // TRUEALERT (Boy Instance de persona); // TRUEALERT (Boy.Constructor == Persona); // falsealert (boy.constructor == objeto); // verdadero
El valor del constructor se puede establecer de las siguientes maneras:
función persona () {} persona.prototype = {constructor: persona, nombre: "xxyh", edad: 18, trabajo: "programador", sayname: function () {alert (this.name); }};3.4 Dinamidad de las cadenas prototipo
Dado que el proceso de encontrar valores en un prototipo es una búsqueda, cualquier modificación realizada al objeto prototipo se refleja en la instancia. Pero si todo el objeto prototipo se reescribe, el resultado será diferente. Al llamar al constructor, se agrega un puntero [[prototipo]] al prototipo original a la instancia, y modificar el prototipo a otro objeto es equivalente a cortar la conexión entre el constructor y el prototipo original. El puntero en la instancia apunta solo al prototipo, no al constructor.
function Person () {} var boy = new Person (); persona.prototype = {constructor: persona, nombre: "xxyh", edad: 29, trabajo: "programador", sayname: function () {alert (this.name); }}; boy.sayname (); // ErrorEl proceso específico es el siguiente:
Como se puede ver desde arriba, la reescritura de objetos prototipo corta la conexión entre los prototipos existentes y cualquier instancia de objeto previamente existente; Se refieren al prototipo original.
3.5 Prototipo de objeto nativo
Todos los tipos de referencia nativos definen métodos en el prototipo del constructor. A través del prototipo del objeto nativo, no solo se puede obtener el método predeterminado, sino que también se puede definir un nuevo método.
String.prototype.startswith = function (text) {return this.indexof (text) == 0;}; var msg = "Good Morning"; Alert (msg.Startswith ("bueno")); // verdadero3.6 Problemas con objetos prototipo
Hay dos problemas con el patrón prototipo:
• Todo el mismo valor de atributo de forma predeterminada.
• Todos los atributos en el prototipo son compartidos por la instancia
Veamos un ejemplo a continuación:
function persona () {} persona.prototype = {constructor: persona, nombre: "xxyh", edad: 18, trabajo: "programador", amigos: ["zhang san", "li si"], sayname: function () {alert (this.name); }}; var p1 = new Person (); var p2 = new Person (); p1.friends.push ("wang wu"); alerta (p1.friends); // Zhang San, Li Si, Wang Wu Alert (P2.Friends); // Zhang San, Li SI, Wang Wu Alert (P1.Friends == P2.Friends); // verdaderoSe agregó un elemento arriba a través de P1. Friends. Dado que la matriz de amigos existe en persona. Prototipo, también se refleja en P2.friends. Sin embargo, las instancias generalmente tienen todos sus propios atributos.
Use el modo constructor y el modo prototipo en combinación
El modo de constructor se utiliza para definir las propiedades de instancia, y el modo prototipo se usa para definir métodos y propiedades compartidas. De esta manera, cada instancia tendrá su propia copia de los atributos de instancia, pero al mismo tiempo compartir una referencia al método.
Función persona (nombre, edad, trabajo) {this.name = name; this.age = edad; this.job = trabajo; this.friends = ["zhang san", "li si"];} persona.prototype = {constructor: persona, sayname: function () {alert (this.name); }} var p1 = nueva persona ("xiao xiao yihan", 18, "programador"); var p2 = nueva persona ("Kuiba", 10, "Hunt Monster"); p1.friends.push ("wang wu"); alerta (p1.friends); // Zhang San, Li SI, alerta de Wang Wu (P2.friends); // Zhang San, Li Si Alert (p1.friends == P2.friends); // falsealSealert (p1.sayname == P2.SayName); // verdaderoEn el ejemplo anterior, las propiedades de instancia se definen en el constructor, mientras que el constructor de propiedades compartido y el método SayName () se definen en el prototipo. La modificación de P1. Los amigos no afectarán los resultados de P2.Friends.
Modo prototipo dinámico
El patrón de prototipo dinámico encapsula toda la información en el constructor e inicializando el prototipo en el constructor, mantiene la ventaja de usar tanto el constructor como el prototipo. Es decir, es posible determinar si el prototipo debe inicializarse verificando si un método que debería existir es efectivo.
Función Persona (nombre, edad, trabajo) {// propiedad this.name = name; this.age = edad; this.job = trabajo; // Método if (typeof this.sayname! = "Function") {persona.prototype.sayname = function () {alert (this.name); }}}Esto solo se agregará al prototipo cuando el método sayname () no exista, y solo se ejecutará cuando el constructor sea llamado por primera vez.
Patrón de constructor parásito
La idea de este patrón es crear una función cuya función es encapsular el código que crea el objeto y luego devolver el objeto recién creado.
Función Persona (nombre, edad) {var obj = new Object (); obj.name = nombre; obj.age = edad; obj.sayName = function () {alert (this.name); } return obj;} var boy = nueva persona ("xxyh", 19, "programador"); boy.sayname ();Cabe señalar: en primer lugar, el objeto devuelto no tiene relación con el constructor o los atributos prototipo del constructor; El objeto devuelto por el constructor no es diferente del objeto creado fuera del constructor. La instancia del operador no se puede confiar para determinar el tipo de objeto.
Patrón de constructor estable
Un objeto seguro se refiere a un objeto que no tiene atributos públicos y sus métodos no se refieren a esto. Los constructores estables siguen un patrón similar a los constructores parásitos, pero hay dos diferencias:
• El método de instancia del objeto recién creado no se refiere a esto;
• El constructor no se llama usar el nuevo operador
Reescribe el constructor de la persona de la siguiente manera:
Función persona (nombre, edad, trabajo) {var obj = new Object (); obj.sayName = function () {alert (nombre); }; regresar obj;} Función persona (nombre, edad, trabajo) {var obj = new Object (); obj.sayName = function () {alert (nombre); }; regresar obj;}El artículo anterior habla brevemente sobre la creación de objetos JavaScript es todo el contenido que comparto con ustedes. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.