Pregunta __proto__ VS. prototipo en JavaScript


Esta figura muestra nuevamente que cada objeto tiene un prototipo. Constructor   función Foo también tiene su propio __proto__ que es Function.prototype,   y que a su vez también hace referencia a través de su __proto__ propiedad de nuevo a   el Object.prototype. Por lo tanto, repito, Foo.prototype es solo un explícito   propiedad de Foo que se refiere al prototipo de objetos byc.

var b = new Foo(20);
var c = new Foo(30);

¿Cuáles son las diferencias entre __proto__ y prototype propiedades?

enter image description here

La figura está tomada de aquí.


599
2018-03-31 21:13


origen


Respuestas:


__proto__ es el objeto real que se utiliza en la cadena de búsqueda para resolver métodos, etc. prototype es el objeto que se usa para construir __proto__ cuando creas un objeto con new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

571
2018-03-31 21:16



prototype es una propiedad de un objeto Function. Es el prototipo de objetos construidos por esa función.

__proto__ es propiedad interna de un objeto, apuntando a su prototipo. Las normas actuales proporcionan un equivalente Object.getPrototypeOf(O) método, aunque de facto estándar __proto__ es mas rapido

Puedes encontrar instanceof relaciones mediante la comparación de una función prototype a un objeto __proto__ cadena, y puede romper estas relaciones cambiando prototype.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

aquí Point es una función constructora, construye un objeto (estructura de datos) procesalmente. myPoint es un objeto construido por Point() asi que Point.prototype se guarda en myPoint.__proto__ En ese tiempo.


278
2018-03-31 21:20



La propiedad prototipo se crea cuando se declara una función.

Por ejemplo:

 function Person(dob){
    this.dob = dob
 }; 

La propiedad person.prototype se crea internamente una vez que declara la función anterior. Se pueden agregar muchas propiedades al Person.prototype que son compartidas por las instancias Person creadas con la nueva Persona ().

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Cabe resaltar que Person.prototype es un Object literal por defecto (se puede cambiar según sea necesario).

Cada instancia creada con la nueva Persona () tiene un __proto__ propiedad que apunta al Person.prototype. Esta es la cadena que se usa para atravesar y encontrar una propiedad de un objeto en particular.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

crea 2 instancias de Persona, estos 2 objetos pueden llamar propiedad de edad de Person.prototype como person1.age, person2.age.

En la imagen de arriba puedes ver que Foo es un Objeto de Función y por lo tanto tiene un __proto__ enlace al Function.prototype que a su vez es una instancia de Object y tiene un __proto__ enlace a Object.prototype. El enlace de proto termina aquí con __proto__ en Object.prototype apuntando a nulo.

Cualquier objeto puede tener acceso a todas las propiedades en su cadena de proto según lo vinculado por __proto__ , formando así la base de la herencia prototípica.

__proto__ no es una forma estándar de acceder a la cadena de prototipos, el enfoque estándar pero similar es usar Object.getPrototypeOf (obj).

Debajo del código para instanceof el operador da una mejor comprensión:

objeto instanceof El operador de clase devuelve true cuando un objeto es una instancia de una clase, más específicamente si Class.prototype se encuentra en la cadena proto de ese objeto, entonces el objeto es una instancia de esa Clase.

function instanceOf(Func){
var obj = this;
while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
        return true;
    obj = Object.getPrototypeOf(obj);
}
return false;
}

El método anterior se puede llamar como: instanceOf.call(object,Class)que devuelve true si object es instancia de Class.


91
2017-08-10 15:27



Una buena forma de pensar es ...

prototype es utilizado por constructor() funciones. Realmente debería haber sido llamado algo así como, "prototypeToInstall", ya que eso es lo que es.

y __proto__ es ese "prototipo instalado" en un objeto (que fue creado / instalado sobre el objeto de dicho constructor() función)


56
2018-05-30 16:26



Prototipo VS. __proto__ VS. [[Prototipo]]

Al crear una función, se llama un objeto de propiedad prototipo se está creando automáticamente (no lo creó usted mismo) y se adjunta al objeto de función (el constructor)
  Nota: Este nuevo prototipo objeto también apunta a, o tiene un enlace interno-privado, el objeto JavaScript nativo.

Ejemplo:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

Si creará un nuevo objeto de Foo utilizando el new palabra clave, usted básicamente crea (entre otras cosas) un nuevo objeto que tiene un enlace interno o privado al prototipo de la función Foo discutimos anteriormente:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


los privado vinculación con el objeto de esa función llamado prototipo de doble paréntesis o simplemente [[Prototype]]. Muchos navegadores nos están proporcionando un público vinculación a lo que llamó __proto__!

Para ser más especifico, __proto__ es en realidad un función getter que pertenecen al objeto JavaScript nativo. Devuelve el enlace de prototipo interno-privado de cualquier this vinculante es (devuelve el [[Prototype]] de b)

b.__proto__ === Foo.prototype // true

Vale la pena señalar que a partir de ECMAScript5, también puedes usar getPrototypeOf método para obtener el enlace privado interno:

Object.getPrototypeOf(b) === b.__proto__ // true


NOTA: esta respuesta no pretende cubrir todo el proceso de creación de nuevos objetos o nuevos constructores, sino ayudar a comprender mejor qué es __proto__, prototype y [[Prototype]] y cómo funciona


38
2017-09-23 12:49



Para explicar, vamos a crear una función

 function a (name) {
  this.name = name;
 }

Cuando JavaScript ejecuta este código, agrega prototype propiedad a a, prototype propiedad es un objeto con dos propiedades:

  1. constructor
  2. __proto__

Entonces cuando lo hacemos

a.prototype vuelve

     constructor: a  // function definition
    __proto__: Object

Ahora como puedes ver constructor no es más que la función a sí mismo y __proto__ apunta al nivel raíz Object de JavaScript.

Veamos qué pasa cuando usamos a funcionar con new palabra clave

var b = new a ('JavaScript');

Cuando JavaScript ejecuta este código, hace 4 cosas:

  1. Crea un nuevo objeto, un objeto vacío // {}
  2. Crea __proto__ en b y hace que apunte a a.prototype asi que b.__proto__ === a.prototype
  3. Ejecuta a.prototype.constructor (que es definición de función a ) con el objeto recién creado (creado en el paso # 1) como su contexto (esto), de ahí el name propiedad pasada como 'JavaScript' (que se agrega a this) se agrega al objeto recién creado.
  4. Devuelve el objeto recién creado en (creado en el paso # 1) por lo que var b se asigna a un objeto recién creado.

Ahora si agregamos a.prototype.car = "BMW" y hacer b.car, aparece la salida "BMW".

esto es porque cuando JavaScript ejecutó este código buscó carpropiedad en b, no encontró JavaScript utilizado b.__proto__ (que fue hecho para apuntar a 'a.prototype' en el paso # 2) y encuentra car propiedad, así que devuelva "BMW".


37
2018-02-02 12:50



Para dejarlo un poco claro además de las excelentes respuestas anteriores:

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

Instancias tener __proto__, clases tener prototipo.


21
2017-10-07 19:26



Otra buena forma de entenderlo:

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

Solo después de IE11 __proto__ esta apoyado. Antes de esa versión, como IE9, podrías usar la constructor para obtener el __proto__.


6
2018-05-12 02:58



Estoy aprendiendo prototipos de Usted no sabe JS: este y Object Prototypes, que es un libro maravilloso para comprender el diseño subyacente y aclarar tantos conceptos erróneos (es por eso que trato de evitar el uso de la herencia y cosas como instanceof)

Pero tengo la misma pregunta que la gente pregunta aquí. Varias respuestas son realmente útiles e ilustrativas. También me encantaría compartir mis entendimientos.


¿Qué es un prototipo?

Los objetos en JavaScript tienen una propiedad interna, indicada en la especificación como[[Prototype]], que es simplemente una referencia a otro objeto. Casi todos los objetos reciben un nonullvalor para esta propiedad, en el momento de su creación.

¿Cómo obtener el prototipo de un objeto?

vía __proto__o Object.getPrototypeOf

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

Cuál es el prototype ?

prototype es un objeto creado automáticamente como una propiedad especial de un función, que se usa para establecer la cadena de delegación (herencia), también conocida como cadena de prototipos.

Cuando creamos una función a, prototype se crea automáticamente como una propiedad especial en a y guarda el código de función como el constructor en prototype.

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

Me encantaría considerar esta propiedad como el lugar para almacenar las propiedades (incluidos los métodos) de un objeto de función. Esa es también la razón por la cual las funciones de utilidad en JS se definen como Array.prototype.forEach() , Function.prototype.bind(), Object.prototype.toString().

Por qué enfatizar la propiedad de un función?

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

Asi que, Arary, Function, Objectson todas las funciones. Debo admitir que esto refresca mi impresión en JS. Sé que las funciones son ciudadanos de primera clase en JS, pero parece que se basa en funciones.

Cuál es la diferencia entre __proto__ y prototype?

__proto__una referencia funciona en cada objeto para referirse a su [[Prototype]]propiedad.

prototype es un objeto creado automáticamente como una propiedad especial de un función, que se usa para almacenar las propiedades (incluidos los métodos) de un objeto de función.

Con estos dos, podríamos mapear mentalmente la cadena de prototipos. Al igual que esta imagen ilustra:

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true

5
2017-07-02 23:14



Para hacerlo mas simple:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

Esto le permite adjuntar propiedades a X.prototype DESPUÉS de que los objetos de tipo X hayan sido instanciados, y aún tendrán acceso a esas nuevas propiedades a través de la referencia de __proto__ que utiliza el motor de Javascript para subir la cadena del prototipo.


4
2017-10-24 07:23