Cada objeto en JavaScript tiene un prototipo de propiedad incorporado. La explicación de la propiedad prototipo de un objeto en JavaScript es: devolver una referencia al prototipo de tipo de objeto. Significa que el atributo prototipo contiene una referencia a otro objeto JavaScript, que actúa como el padre del objeto actual.
La copia del código es la siguiente:
A.Prototype = new B ();
Comprender el prototipo no debe confundirse con la herencia. El prototipo de A es una instancia de B. Se puede entender que un clonado todos los métodos y propiedades en B. A puede usar los métodos y propiedades de B. Lo que se enfatiza aquí es la clonación en lugar de la herencia. Esto puede suceder: el prototipo de A es una instancia de B, y el prototipo de B también es una instancia de A.
Continúe mirando el siguiente análisis:
Variables y funciones privadas
Si las variables y las funciones definidas dentro de la función no se proporcionan externamente, no se puede acceder externamente, es decir, las variables privadas y las funciones de la función.
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {
var color = "azul"; // variable privada
var fn = function () // función privada
{
}
}
</script>
De esta manera, no se puede acceder a las variables color y FN fuera del cuadro de objeto de función, y se vuelven privados:
La copia del código es la siguiente:
var obj = new Box ();
alerta (obj.color); // pop-up indefinido
alerta (obj.fn); // Igual que el anterior
Variables y funciones estáticas
Cuando se define una función, los atributos y funciones agregados a ella todavía se pueden acceder a través del objeto en sí, pero no se puede acceder a sus ejemplos. Dichas variables y funciones se denominan variables estáticas y funciones estáticas, respectivamente.
La copia del código es la siguiente:
<script type = "text/javaScript">
función obj () {};
Obj.num = 72; // variable estática
Obj.fn = function () // función estática
{
}
alerta (obj.num); // 72
alerta (typeof obj.fn) // función
var t = nuevo obj ();
alerta (t.name); // indefinido
alerta (typeof t.fn); // indefinido
</script>
Variables y funciones de instancia
En la programación orientada a objetos, además de algunas funciones de la biblioteca, aún esperamos definir algunas propiedades y métodos al mismo tiempo cuando la definición de objetos, para que se pueda acceder después de la instancia, y JS también puede hacerlo.
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {
this.a = []; // Variable de instancia
this.fn = function () {// método de instancia
}
}
console.log (typeof box.a); //indefinido
console.log (typeof box.fn); //indefinido
var box = new Box ();
console.log (typeof box.a); //objeto
console.log (typeof box.fn); //función
</script>
Agregar nuevos métodos y propiedades a las variables y métodos de instancia
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {
this.a = []; // Variable de instancia
this.fn = function () {// método de instancia
}
}
var box1 = new Box ();
box1.a.push (1);
box1.fn = {};
console.log (box1.a); // [1]
console.log (typeof box1.fn); //objeto
var box2 = new Box ();
console.log (box2.a); // []
console.log (typeof box2.fn); //función
</script>
A y FN se modificaron en Box1, pero no en Box2. Dado que las matrices y las funciones son objetos y son tipos de referencia, esto significa que aunque las propiedades y los métodos en el cuadro1 son los mismos que en el cuadro2, no son una referencia, sino una copia de las propiedades y métodos definidos por el objeto del cuadro.
Esto no tiene ningún problema con las propiedades, pero es un gran problema para los métodos, porque los métodos están haciendo exactamente la misma función, pero hay dos copias. Si un objeto de función tiene miles y métodos de instancia, entonces cada instancia debe mantener una copia de miles de métodos. Esto es obviamente no científico. ¿Qué puedo hacer? El prototipo surgió.
Conceptos básicos
Cada función que creamos tiene una propiedad prototipo, que es un puntero a un objeto, y su propósito es contener propiedades y métodos que pueden compartir por todas las instancias de un tipo específico. Luego, el prototipo es el objeto prototipo de la instancia de objeto creada llamando al constructor.
La ventaja de usar un prototipo es que permite que una instancia de objeto comparta las propiedades y métodos que contiene. Es decir, en lugar de agregar información de objetos de definición al constructor, puede agregar directamente esta información al prototipo. El principal problema con el uso de constructores es que cada método debe crearse una vez en cada instancia.
En JavaScript, hay dos tipos de valores, valores originales y valores de objeto. Cada objeto tiene un prototipo de propiedad interna, que generalmente llamamos un prototipo. El valor del prototipo puede ser un objeto o nulo. Si su valor es un objeto, el objeto también debe tener su propio prototipo. Esto forma una cadena lineal, que llamamos la cadena prototipo.
significado
Las funciones se pueden usar como constructores. Además, solo la función tiene un atributo prototipo y se puede acceder, pero la instancia del objeto no tiene este atributo, solo hay un atributo __proto__ inaccesible interno inaccesible. __proto__ es un enlace misterioso en el objeto al prototipo relevante. Según el estándar, __proto__ no se revela al público, lo que significa que es una propiedad privada, pero el motor de Firefox lo expuso y se convirtió en una propiedad común, a la que podemos acceder y establecer.
La copia del código es la siguiente:
<script type = "text/javaScript">
var browser = function () {};
Browser.prototype.run = function () {
alerta ("Soy Gecko, un núcleo de Firefox");
}
var bro = nuevo navegador ();
Bro.run ();
</script>
Cuando llamamos al método bro.run (), ya que no existe tal método en Bro, lo buscará en su __proto__, es decir, navegador.prototype, por lo que el método run () finalmente se ejecuta. (Aquí, la letra capitalizada de la función representa el constructor para distinguir las funciones ordinarias)
Al llamar al constructor para crear una instancia, la instancia contendrá un puntero interno (__proto__) que apunta al prototipo del constructor. Esta conexión existe entre la instancia y el prototipo del constructor, no entre la instancia y el constructor.
La copia del código es la siguiente:
<script type = "text/javaScript">
Función Persona (nombre) {// Función de constructor
this.name = name;
}
Persona.prototype.printname = function () // objeto prototipo
{
alerta (this.name);
}
VAR Person1 = nueva persona ('byron'); // instanciar el objeto
console.log (persona1 .__ proto __); // Persona
console.log (persona1.constructor); // Pruébelo usted mismo para ver lo que será
console.log (persona.prototype); // señala a la persona de objeto prototipo
var persona2 = nueva persona ('frank');
</script>
Instance de la persona La persona1 contiene el atributo de nombre, y genera automáticamente un atributo __proto__, que apunta al prototipo de la persona, y puede acceder al método de nombre de impresión definido en el prototipo, que probablemente sea así:
Cada función de JavaScript tiene un atributo prototipo, que se refiere a un objeto, que es el objeto prototipo. El objeto prototipo está vacío cuando se inicializa. Podemos personalizar cualquier propiedad y método en él. Estos métodos y propiedades serán heredados por los objetos creados por el constructor.
Entonces, ahora el problema es. ¿Cuál es la relación entre constructor, instancia y objeto prototipo?
La diferencia entre constructores, instancias y objetos prototipo
Se crea una instancia a través de un constructor. Una vez que se crea una instancia, tiene el atributo de constructor (apuntando a la función del constructor) y el atributo __proto__ (apuntando al objeto prototipo).
Hay una propiedad prototipo en el constructor, que es un puntero a su objeto prototipo.
También hay un puntero (propiedad del constructor) dentro del objeto prototipo que apunta al constructor: persona.prototype.constructor = persona;
Las instancias pueden acceder a propiedades y métodos definidos en el objeto prototipo.
Aquí Person1 y Person2 son instancias, y el prototipo son sus objetos prototipo.
Otro castaño:
La copia del código es la siguiente:
<script type = "text/javaScript">
función animal (nombre) // acumular constructor
{
this.name = name; // Establecer propiedades del objeto
}
Animal.prototype.behavior = function () // Agregar método de comportamiento al prototipo del constructor de clase base
{
alerta ("esto es un"+this.name);
}
var dog = nuevo animal ("perro"); // Crear objeto de perro
var cat = nuevo animal ("gato"); // Crear objeto de gato
Dog.behavior (); // llame al método de comportamiento directamente a través del objeto del perro
Cat.Behavior (); // Salida "Este es un gato"
alerta (dog.behavior == Cat.Behavior); // Salida True;
</script>
Se puede ver en el programa que ejecuta resultados que los métodos definidos en el prototipo del constructor pueden llamarse directamente a través del objeto, y el código se comparte. (Puede intentar eliminar la propiedad prototipo en animal.prototype.behavior para ver si aún puede funcionar.) Aquí, la propiedad prototipo apunta al objeto animal.
Instancia de objeto de matriz
Veamos una instancia del objeto de matriz. Cuando creamos la matriz de objetos1, el modelo de objeto real de Array1 en el motor JavaScript es el siguiente:
La copia del código es la siguiente:
varilla var1 = [1,2,3];
El objeto Array1 tiene un valor de atributo de longitud de 3, pero podemos agregar elementos a Array1 por el siguiente método:
La copia del código es la siguiente:
array1.push (4);
El método push proviene de un método que apunta al objeto por el miembro __proto__ de Array1 (Array.Prototye.push ()). Se debe precisamente a que todos los objetos de matriz (creados a través de []) contienen un miembro __proto__ que apunta al mismo objeto de método con Push, Reverse, etc. (Array.Prototype), que estos objetos de matriz pueden usar Push, Reverse y otros métodos.
Instancia de objeto de función
La copia del código es la siguiente:
función base () {
this.id = "base"
}
La copia del código es la siguiente:
var obj = new Base ();
¿Cuál es el resultado de dicho código? El modelo de objeto que vemos en el motor JavaScript es:
¿Qué hizo exactamente el nuevo operador? De hecho, fue muy simple, solo hizo tres cosas.
La copia del código es la siguiente:
var obj = {};
obj .__ proto__ = base.prototype;
Base.call (obj);
Cadena prototipo
Cadena prototipo: cuando se recupera una propiedad o método de un objeto, si el objeto en sí no tiene dicha propiedad o método, buscará el objeto prototipo con el que asocia. Si no hay un prototipo, buscará el predecesor de prototipo asociado con el prototipo. Si no hay más, continúe buscando el objeto referenciado por Prototype.prototype, y así sucesivamente hasta que el prototipo ... el prototipo no esté definido (el prototipo del objeto está indefinido), formando así la llamada "cadena prototipo".
La copia del código es la siguiente:
<script type = "text/javaScript">
Function Shape () {
this.name = "forma";
this.ToString = function () {
devolver esto.name;
}
}
función twoshape () {
this.name = "2 forma";
}
Triángulo de función (lado, altura) {
this.name = "triángulo";
this.side = lado;
this.Height = altura;
this.getArea = function () {
devuelve esto.side*this.Height/2;
}
}
Twoshape.prototype = new Shape ();
Triangle.prototype = new Twoshape ();
</script>
Aquí, se crea una nueva entidad con la forma del constructor (), y luego se usa para sobrescribir el prototipo del objeto.
La copia del código es la siguiente:
<script type = "text/javaScript">
Function Shape () {
this.name = "forma";
this.ToString = function () {
devolver esto.name;
}
}
función twoshape () {
this.name = "2 forma";
}
Triángulo de función (lado, altura) {
this.name = "triángulo";
this.side = lado;
this.Height = altura;
this.getArea = function () {
devuelve esto.side*this.Height/2;
}
}
Twoshape.prototype = new Shape ();
Triangle.prototype = new Twoshape ();
Twoshape.prototype.constructor = twoshape;
Triangle.prototype.constructor = triangle;
var my = nuevo triángulo (5,10);
my.getArea ();
my.ToString (); // triángulo
my.constructor; // triángulo (lado, altura)
</script>
Herencia prototipo
Herencia prototipo: al final de la cadena prototipo, es el objeto prototipo apuntado por el atributo prototipo del constructor de objeto. Este objeto prototipo es el antepasado de todos los objetos, y este antepasado implementó métodos que todos los objetos como la tostración deberían haber tenido innatamente. Otros constructores incorporados, como la función, el booleano, la cadena, la fecha y el regexp, se heredan de este antepasado, pero cada uno define sus propios atributos y métodos, para que sus descendientes muestren las características de sus respectivos clanes.
En ECMAScript, el método de implementación de la herencia se logra dependiendo de la cadena de prototipos.
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {// La función heredada se llama supertipo (clase principal, clase base)
this.name = "Jack";
}
function tree () {// Las funciones hereditarias se denominan subtipos (subclases, clases derivadas)
this.age = 300;
}
// Heredar a través de la cadena prototipo, asigne los atributos prototipo del subtipo
// nuevo cuadro () entregará la información en la construcción del cuadro y la información en el prototipo al árbol
Tree.prototype = new Box (); // Tree hereda el cuadro y forma una cadena a través del prototipo.
var árbol = nuevo árbol ();
alerta (árbol.name); // Popt Jack
</script>
Problema con la cadena prototipo: aunque la cadena prototipo es muy poderosa y puede usarse para implementar la herencia, también tiene algunos problemas. El problema más importante proviene del prototipo de valor que contiene el tipo de referencia. Los atributos prototipo que contienen tipos de referencia son compartidos por todas las instancias; Esta es la razón por la cual los atributos se definen en constructores, no en objetos prototipo. Cuando se logra la herencia a través de un prototipo, el prototipo en realidad se convierte en una instancia de otro tipo. Por lo tanto, el atributo de instancia original se convierte en el atributo prototipo.
Al crear una instancia de un subtipo, el argumento no puede pasar al constructor Supertype. De hecho, debe decirse que no hay forma de pasar parámetros al constructor Supertype sin afectar todas las instancias de objetos. Además del problema que acaba de discutir debido a la inclusión de valores de tipo de referencia en los prototipos, es raro usar cadenas prototipo solas en la práctica.
Otro castaño:
La copia del código es la siguiente:
<script type = "text/javaScript">
Persona de función (nombre)
{
this.name = name; // Establecer propiedades del objeto
};
Persona.prototype.company = "Microsoft"; // Establezca las propiedades del prototipo
Persona.prototype.sayhello = function () // método prototipo
{
alerta ("Hola, soy"+ this.name+ "de"+ this.comPany);
};
var billgates = nueva persona ("billgates"); // crear objeto de persona
Billgates.sayhello (); // hereda el contenido del prototipo y salidas "Hola, soy Billgates de Microsoft"
var trabajos = nueva persona ("trabajos");
Jobs.company = "Apple"; // Establezca su propio atributo de empresa para encubrir el atributo de la compañía del prototipo
Jobs.sayhello = function ()
{
alerta ("hola" + this.name + "me gusta" + this.comPany);
};
Jobs.sayhello (); // Las propiedades y métodos que se anulan a sí mismos, emiten "Hola, trabajos como Apple"
Billgates.sayhello (); // La cobertura de trabajos no afecta el prototipo, Billgates aún sale
</script>
Vea el siguiente ejemplo de la cadena prototipo:
La copia del código es la siguiente:
<script type = "text/javaScript">
function Year () {
this.value = 21;
}
Año.prototype = {
Método: function () {
}
};
función hi () {
};
// establecer la propiedad prototipo de HI en el objeto de instancia del año
Hi.prototype = nuevo año ();
Hi.prototype.year = 'Hello World';
Hi.prototype.constructor = HI;
var test = new Hi (); // Cree una nueva instancia de HI
// cadena prototipo
Prueba [HI Ejemplo]
Hola. Prototipo [Ejemplo de año]
{año: 'Hola mundo'}
Año.prototipo
{método:…};
objeto.prototipo
{toString: ...};
</script>
Del ejemplo anterior, el objeto de prueba se hereda de Hi.Prototype y Year.Prototype; Por lo tanto, puede acceder al método del método prototipo de año, y al mismo tiempo puede acceder al valor de la propiedad de la instancia
__ptoto__ atributo
El atributo __ptoto__ (no compatible con el navegador IE) es un puntero al objeto prototipo de la instancia. Su función es señalar el constructor de atributos prototipo del constructor. A través de estos dos atributos, puede acceder a las propiedades y métodos en el prototipo.
Una instancia de objeto en JavaScript está esencialmente compuesta de una serie de propiedades. Entre estas propiedades, hay una propiedad especial invisible internamente: __proto__. El valor de esta propiedad apunta al prototipo de la instancia del objeto. Una instancia de objeto solo tiene un prototipo único.
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {// uppercase, representando el constructor
Box.prototype.name = "trigkit4"; // atributos prototipo
Box.prototype.age = "21";
Box.prototype.run = function () // método prototipo
{
devuelve this.name + this.age + 'estudiando';
}
}
var box1 = new Box ();
var box2 = new Box ();
alerta (box1.constructor); // Construye el atributo, puede obtener el constructor en sí,
// La función debe ser colocada por el puntero prototipo y luego obtener el constructor en sí
</script>
La diferencia entre el atributo __proto__ y el atributo prototipo
El prototipo es una propiedad propietaria en el objeto de función.
__proto__ es una propiedad implícita de un objeto normal. Cuando sea nuevo, apuntará al objeto señalado por el prototipo;
__ptoto__ es en realidad un atributo de un cierto objeto de entidad, mientras que el prototipo es un atributo que pertenece al constructor. __ptoto__ solo se puede usar en entornos de aprendizaje o depuración.
Proceso de ejecución del modo prototipo
1. Primero busque los atributos o métodos en la instancia del constructor, y de ser así, regrese de inmediato.
2. Si no hay ninguna instancia del constructor, vaya a su objeto prototipo y regrese inmediatamente.
Objeto prototipo
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {// uppercase, representando el constructor
Box.prototype.name = "trigkit4"; // atributos prototipo
Box.prototype.age = "21";
Box.prototype.run = function () // método prototipo
{
devuelve this.name + this.age + 'estudiando';
}
}
var box1 = new Box ();
alerta (box1.name); // trigkit4, el valor en el prototipo
box1.name = "Lee";
alerta (box1.name); // lee, vaya al principio
var box2 = new Box ();
alerta (box2.name); // trigkit4, el valor del prototipo, no modificado por Box1
</script>
El constructor
La copia del código es la siguiente:
<script type = "text/javaScript">
function box () {
this.name = "bill";
}
Box.prototype.name = "trigkit4"; // atributos prototipo
Box.prototype.age = "21";
Box.prototype.run = function () // método prototipo
{
devuelve this.name + this.age + 'estudiando';
}
var box1 = new Box ();
alerta (box1.name); // factura, el valor en el prototipo
box1.name = "Lee";
alerta (box1.name); // lee, vaya al principio
</script>
Para resumir, solucionémoslo:
La copia del código es la siguiente:
<script type = "text/javaScript">
función persona () {};
Persona.prototype.name = "trigkit4";
Persona.prototype.say = function () {
alerta ("hi");
}
var p1 = nueva persona (); // El prototipo es un objeto prototipo de P1 y P2
var p2 = nueva persona (); // p2 es un objeto instanciado, y hay un atributo __proto__ dentro de él, apuntando al prototipo de la persona
console.log (p1.prototype); // indefinido, esta propiedad es un objeto y no se puede acceder
console.log (persona.prototype); // persona
console.log (persona.prototype.constructor); // También hay un puntero (propiedad del constructor) dentro del objeto prototipo que apunta a la función del constructor
console.log (p1 .__ proto __); // Esta propiedad es un puntero que apunta al objeto prototipo del prototipo
p1.say (); // Las instancias pueden acceder a propiedades y métodos definidos en el objeto prototipo
</script>
Modelo de fábrica
La copia del código es la siguiente:
función createObject (nombre, edad) {
var obj = nuevo objeto ();
obj.name = nombre;
obj.age = edad;
regresar obj;
}
El patrón de fábrica resuelve el problema de la duplicación a gran escala de objetos instanciados, pero hay otro problema, es decir, es imposible descubrir qué instancia del objeto son.
El uso del método del constructor no solo resuelve el problema de la instanciación repetida, sino que también resuelve el problema del reconocimiento de objetos.
La diferencia entre el uso de métodos de constructor y patrones de fábrica es que:
1. Crear objeto (nuevo objeto ()) que no se muestra por el método del constructor;
2. Asigne directamente atributos y métodos a este objeto
3. Sin declaración de devolución
Cuando se usa el constructor y se usa el nuevo constructor (), el nuevo objeto () se ejecuta en segundo plano;
Esto en el cuerpo de la función representa el objeto derivado del nuevo objeto ()
1. Determine si la propiedad está en la instancia del constructor o en el prototipo, puede usar la función `iSownProperty ()`
2. La forma de crear literales se usa para crear atributos de constructor no apuntará a la instancia, sino al objeto, y la forma de crear constructores es lo contrario.
¿Por qué apuntar a objetar? Porque box.prototype = {}; esta forma de escribir es realmente crear un nuevo objeto.
Cada vez que se crea una función, su prototipo se creará al mismo tiempo, y este objeto obtendrá automáticamente el atributo Constructor
3. Si es un método de instancia, una instanciación diferente, sus direcciones de método son diferentes y únicas.
4. Si es un método prototipo, entonces su dirección se comparte