ejemplos - __proto__ VS. prototipo en JavaScript
prototype javascript tutorial (25)
Esta figura muestra nuevamente que cada objeto tiene un prototipo. La función constructora 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 propiedad__proto__
nuevo al Object.prototype. Por lo tanto, repita, Foo.prototype es solo una propiedad explícita de Foo que se refiere al prototipo de los objetos b y c.
var b = new Foo(20);
var c = new Foo(30);
¿Cuáles son las diferencias entre __proto__
y las propiedades del prototype
?
La figura está tomada desde here .
Resumen:
La __proto__
propiedad de un objeto es una propiedad que se asigna a la prototype
función constructora del objeto. En otras palabras:
instance.__proto__ === constructor.prototype // true
Esto se utiliza para formar la prototype
cadena de un objeto. La prototype
cadena es un mecanismo de búsqueda de propiedades en un objeto. Si se accede a la propiedad de un objeto, Javascript primero buscará en el objeto en sí mismo, si la propiedad no se encuentra allí, ascenderá protochain
hasta que se encuentre (o no)
Ejemplo:
function Person (name, city) {
this.name = name;
}
Person.prototype.age = 25;
const willem = new Person(''Willem'');
console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor
console.log(willem.age); // 25 doesn''t find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function
Nuestro primer registro de resultados true
es porque como se mencionó, la __proto__
propiedad de la instancia creada por el constructor se refiere a la prototype
propiedad del constructor. Recuerde que en las funciones de Javascript también son objetos. Los objetos pueden tener propiedades, y una propiedad predeterminada de cualquier función es una propiedad llamada prototipo.
Luego, cuando esta función se utiliza como una función de constructor, la forma del objeto instanciada recibirá una propiedad llamada __proto__
. Y esta __proto__
propiedad se refiere a la prototype
propiedad de la función constructora (que por defecto tiene cada función).
¿Por qué es esto útil?
Javascript tiene un mecanismo cuando se buscan propiedades en las Objects
que se llama ''herencia prototípica'' , esto es lo que básicamente hace:
- Primero se comprueba si la propiedad se encuentra en el objeto en sí. Si es así se devuelve esta propiedad.
- Si la propiedad no se encuentra en el objeto en sí, "escalará la protocta". Básicamente, mira el objeto referido por la
__proto__
propiedad. Allí verifica si la propiedad está disponible en el objeto referido por__proto__
- Si la propiedad no está ubicada en el
__proto__
objeto, subirá la__proto__
cadena hasta elObject
objeto. - Si no puede encontrar la propiedad en ninguna parte del objeto y su
prototype
cadena, se devolveráundefined
.
Por ejemplo:
function Person (name) {
this.name = name;
}
let mySelf = new Person(''Willem'');
console.log(mySelf.__proto__ === Person.prototype);
console.log(mySelf.__proto__.__proto__ === Object.prototype);
prototipo
El prototipo es una propiedad de una función. Es el plan para crear objetos utilizando esa función (constructor) con una nueva palabra clave.
__proto__
__proto__
se utiliza en la cadena de búsqueda para resolver métodos y propiedades. cuando se crea un objeto (usando la función de constructor con una nueva palabra clave), __proto__
se establece en (Constructor) Function.prototype
function Robot(name) {
this.name = name;
}
var robot = new Robot();
// the following are true
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype
Aquí está mi explicación (imaginaria) para aclarar la confusión:
Imagine que hay una clase imaginaria (blueprint / coockie cutter) asociada con la función. Esa clase imaginaria se usa para instanciar objetos. prototype
es el mecanismo de extensión (método de extensión en C # o Swift Extension) para agregar cosas a esa clase imaginaria.
function Robot(name) {
this.name = name;
}
Lo anterior se puede imaginar como:
// imaginary class
class Robot extends Object{
static prototype = Robot.class
// Robot.prototype is the way to add things to Robot class
// since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
}
Asi que,
var robot = new Robot();
robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype
Ahora añadiendo método al prototype
de robot:
Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)
Lo anterior se puede imaginar como extensión de la clase Robot:
// Swift way of extention
extension Robot{
function move(x, y){
Robot.position.x = x; Robot.position.y = y
}
}
Que a su vez,
// imaginary class
class Robot{
static prototype = Robot.class // Robot.prototype way to extend Robot class
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
// added by prototype (as like C# extension method)
function move(x, y){
Robot.position.x = x; Robot.position.y = y
};
}
Prototipo VS. __proto__ VS. [[Prototipo]]
Al crear una función, un objeto de propiedad llamado prototipo se crea automáticamente (usted no lo creó usted mismo) y se adjunta al objeto de función (el constructor
).
Nota : este nuevo objeto prototipo también apunta, o tiene un enlace interno-privado, al objeto nativo de JavaScript.
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 a partir de Foo
usando la new
palabra clave, básicamente creará (entre otras cosas) un nuevo objeto que tiene un enlace interno o privado al prototipo de la función Foo
que discutimos anteriormente:
var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
El enlace privado al objeto de esa función llamado prototipo de corchetes dobles o simplemente [[Prototype]]
. Muchos navegadores nos proporcionan un enlace público que se llama __proto__
!
Para ser más específico, __proto__
es en realidad una función getter que pertenece al objeto JavaScript nativo. Devuelve el enlace prototipo interno-privado de lo que sea this
enlace (devuelve el [[Prototype]]
de b
):
b.__proto__ === Foo.prototype // true
Vale la pena señalar que al iniciar ECMAScript5
, también puede usar el método getPrototypeOf para obtener el enlace privado interno:
Object.getPrototypeOf(b) === b.__proto__ // true
NOTA: esta respuesta no pretende abarcar todo el proceso de creación de nuevos objetos o nuevos constructores, sino que ayuda a comprender mejor qué es __proto__
, prototype
y [[Prototype]]
y cómo funciona.
DEFINICIONES
(el número dentro del paréntesis () es un "enlace" al código que se escribe a continuación)
prototype
- un objeto que consiste en:
=> funciones (3) de este particular ConstructorFunction.prototype
(5) que son accesibles por cada objeto (4) creado o por crear a través de esta función de constructor (1)
=> la propia función constructora (1)
=> __proto__
de este objeto particular (objeto prototipo)
__proto__
(dandor proto?) - un enlace ENTRE cualquier objeto (2) creado a través de una función constructora particular (1), Y las propiedades del objeto prototipo (5) de ese constructor QUE permite que cada objeto creado (2) tenga acceso a los prototipos funciones y métodos (4) ( __proto__
está incluido por defecto en cada objeto en JS)
CLARIFICACIÓN DEL CÓDIGO
1.
function Person (name, age) {
this.name = name;
this.age = age;
}
2.
var John = new Person(‘John’, 37);
// John is an object
3.
Person.prototype.getOlder = function() {
this.age++;
}
// getOlder is a key that has a value of the function
4.
John.getOlder();
5.
Person.prototype;
Cada función que creas tiene una propiedad llamada prototype
, y comienza su vida como un objeto vacío. Esta propiedad no sirve de nada hasta que use esta función como función constructora, es decir, con la palabra clave ''nuevo''.
Esto se confunde a menudo con la propiedad __proto__
de un objeto. Algunos podrían confundirse y excepto que la propiedad prototype
de un objeto podría obtener el prototype
de un objeto. Pero este no es el caso. prototype
se utiliza para obtener el __proto__
de un objeto creado a partir de un constructor de funciones.
En el ejemplo anterior:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__
Espero que tenga sentido.
En JavaScript, una función se puede utilizar como un constructor. Eso significa que podemos crear objetos a partir de ellos usando la nueva palabra clave. Cada función constructora viene con un objeto incorporado encadenado con ellos. Este objeto incorporado se llama un prototipo. Instances of a constructor function use __proto__ to access the prototype property of its constructor function.
Primero creamos un constructor:
function Foo(){}
. Para ser claros, Foo es simplemente otra función. Pero podemos crear un objeto a partir de él con la nueva palabra clave. Por eso lo llamamos la función constructora.Cada función tiene una propiedad única que se llama la propiedad prototipo. Entonces, la función Constructor
Foo
tiene una propiedad prototipo que apunta a su prototipo, que esFoo.prototype
(ver imagen).Las funciones de constructor son en sí mismas una función que es una instancia de un constructor de sistema llamado el [[Función]] constructor. Entonces podemos decir que la
function Foo
está construida por un [[Función]] constructor. Entonces,__proto__
de nuestraFoo function
apuntará al prototipo de su constructor, que esFunction.prototype
.Function.prototype
no es más que un objeto construido a partir de otro constructor del sistema llamado[[Object]]
. Entonces,[[Object]]
es el constructor deFunction.prototype
. Entonces, podemos decir queFunction.prototype
es una instancia de[[Object]]
. Así que__proto__
deFunction.prototype
apunta aObject.prototype
.Object.prototype
es el último hombre en pie en la cadena de prototipos. Quiero decir que no ha sido construido. Ya está ahí en el sistema. Así que su__proto__
apunta anull
.Ahora llegamos a instancias de
Foo
. Cuando creamos una instancia utilizando elnew Foo()
, crea un nuevo objeto que es una instancia deFoo
. Eso significa queFoo
es el constructor de estas instancias. Aquí creamos dos instancias (x e y).__proto__
de x e y, por lo tanto, apunta aFoo.prototype
.
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. Muchas propiedades se pueden agregar al Person.prototype que son compartidas por las instancias de Person creadas usando la nueva Person ().
// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob};
Vale la pena señalar que Person.prototype
es un Object
literal de forma predeterminada (se puede cambiar según sea necesario).
Cada instancia creada utilizando new Person () tiene una propiedad __proto__
que apunta al Person.prototype. Esta es la cadena que se utiliza para recorrer una propiedad de un objeto en particular.
var person1 = new Person(somedate);
var person2 = new Person(somedate);
crea 2 instancias de Person, estos 2 objetos pueden llamarse age propiedad de Person.prototype como person1.age, person2.age.
En la imagen anterior puede ver que Foo es un Objeto de función y, por lo tanto, tiene un enlace __proto__
al __proto__
que a su vez es una instancia de Objeto y tiene un enlace __proto__ al Objeto.prototipo. El enlace proto termina aquí con __proto__
en el prototipo Object. apuntando a nulo.
Cualquier objeto puede tener acceso a todas las propiedades en su cadena de proto como lo vincula __proto__
, formando así la base para 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).
El siguiente código para el operador de instanceof
da una mejor comprensión:
object instanceof
Class operador devuelve true
cuando un objeto es una instancia de una clase, más específicamente si Class.prototype
se encuentra en la cadena de 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 puede llamarse como: instanceOf.call(object,Class)
que devuelve verdadero si el objeto es una instancia de Clase.
Lo sé, llego tarde pero déjame intentar simplificarlo.
Digamos que hay una función
function Foo(message){
this.message = message ;
};
console.log(Foo.prototype);
La función de Foo tendrá un objeto prototipo vinculado. Por lo tanto, siempre que creamos una función en JavaScript, siempre tiene un objeto prototipo vinculado a ella.
Ahora vamos a seguir adelante y crear dos objetos usando la función Foo.
var a = new Foo("a");
var b = new Foo("b");
console.log(a.message);
console.log(b.message);
- Ahora tenemos dos objetos, objeto a y objeto b. Ambos se crean utilizando el constructor Foo. Tenga en cuenta que el constructor es sólo una palabra aquí.
- Tanto el objeto a como el b tienen una copia de la propiedad del mensaje.
- Estos dos objetos a y b están vinculados al objeto prototipo del constructor Foo.
- En los objetos a y b, podemos acceder al prototipo Foo utilizando la propiedad proto en todos los navegadores y en IE podemos usar Object.getPrototypeOf (a) o Object.getPrototypeOf (b)
Ahora, Foo.prototype, a. proto , y b. proto todo denota el mismo objeto.
b.__proto__ === Object.getPrototypeOf(a);
a.__proto__ === Foo.prototype;
a.constructor.prototype === a.__proto__;
Todo lo anterior volvería verdad.
Como sabemos, en las propiedades de JavaScript se pueden agregar dinámicamente. Podemos añadir propiedad al objeto.
Foo.prototype.Greet = function(){
console.log(this.message);
}
a.Greet();//a
b.Greet();//b
a.constructor.prototype.Greet();//undefined
Como puede ver, agregamos el método Greet () en Foo.prototype, pero es accesible en a y b o en cualquier otro objeto construido con Foo.
Al ejecutar a.Greet (), JavaScript primero buscará Greet en el objeto a en la lista de propiedades. Al no encontrarlo, subirá en proto cadena de a. Desde un. proto y Foo.prototype es el mismo objeto, JavaScript encontrará el método Greet () y lo ejecutará.
Espero, ahora prototipo y proto se simplifica un poco.
Otra buena manera 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 que IE11 __proto__
sea compatible. Antes de esa versión, como IE9, puedes usar el constructor
para obtener __proto__
.
Para explicar creamos una función.
function a (name) {
this.name = name;
}
Cuando JavaScript ejecuta este código, agrega una propiedad de prototype
a a
, la propiedad de prototype
es un objeto con dos propiedades:
-
constructor
-
__proto__
Así que cuando lo hacemos
a.prototype
devuelve
constructor: a // function definition
__proto__: Object
Ahora, como puede ver, el constructor
no es más que la función a
sí misma y __proto__
apunta al Object
de nivel raíz de JavaScript.
Veamos qué sucede cuando usamos a
función con una new
palabra clave.
var b = new a (''JavaScript'');
Cuando JavaScript ejecuta este código hace 4 cosas:
- Crea un nuevo objeto, un objeto vacío // {}
- Crea
__proto__
enb
y lo hace apuntar aa.prototype
así queb.__proto__ === a.prototype
- Ejecuta
a.prototype.constructor
(que es la definición de la funcióna
) con el objeto recién creado (creado en el paso # 1) como su contexto (esto), por lo tanto, la propiedad delname
pasa como ''JavaScript'' (que se agrega athis
) se agrega al objeto recién creado. - Devuelve el objeto recién creado en (creado en el paso # 1), por lo que var
b
se asigna al objeto recién creado.
Ahora, si agregamos a.prototype.car = "BMW"
y hacemos b.car
, b.car
la salida "BMW".
esto se debe a que cuando JavaScript ejecutó este código, buscó una propiedad de car
en b
, no encontró, entonces, JavaScript utilizó b.__proto__
(que se hizo para apuntar a ''un.prototipo'' en el paso # 2) y encuentra una propiedad de car
así que devuélvalo BMW".
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 los objetos X.prototype AFTER del tipo X, y aún así tendrán acceso a esas nuevas propiedades a través de la referencia __proto__ que usa el motor de Javascript para subir la cadena del prototipo.
Para que quede un poco claro, además de las grandes respuestas anteriores:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
eve.__proto__ == Person.prototype //true
eve.prototype //undefined
Las instancias tienen __proto__ , las clases tienen prototipo .
Resulta que estoy aprendiendo un prototipo de You Don''t Know JS: this y Object Prototypes , que es un libro maravilloso para entender el diseño que se encuentra debajo y aclarar tantas ideas erróneas (por eso estoy tratando 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 y esclarecedoras. 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. A casi todos los objetos se les asigna un valor no null
para esta propiedad, en el momento de su creación.
¿Cómo conseguir el prototipo de un objeto?
a través de __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
¿Qué es el prototype
?
prototype
es un objeto creado automáticamente como una propiedad especial de una función , que se utiliza para establecer la cadena de delegación (herencia), también conocida como cadena de prototipo.
Cuando creamos una función a
, el prototype
se crea automáticamente como una propiedad especial en ay guarda el código de la función como constructor
en el 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 que las funciones de utilidad en JS se definen como Array.prototype.forEach()
, Function.prototype.bind()
, Object.prototype.toString().
¿Por qué enfatizar la propiedad de una 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();
Entonces, Arary
, Function
, Object
son todas 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 propiedad [[Prototype]]
.
prototype
es un objeto creado automáticamente como una propiedad especial de una función , que se utiliza para almacenar las propiedades (incluidos los métodos) de un objeto de función.
Con estos dos, podríamos mapear mentalmente la cadena del prototipo. Como ilustra esta imagen:
function Foo() {}
var b = new Foo();
b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Una buena manera de pensarlo es ...
prototype
es usado por las funciones constructor()
. Realmente debería haberse llamado algo así como "prototypeToInstall"
, ya que eso es lo que es.
y __proto__
es ese "prototipo instalado" en un objeto (que se creó / instaló en el objeto desde dicha función constructor()
)
Voy a intentar una explicación de cuarto grado:
Las cosas son muy simples. Un prototype
es un ejemplo de cómo se debe construir algo. Asi que:
Soy una
function
y construyo nuevos objetos similares a miprototype
Soy un
object
y fui construido usando mi__proto__
como ejemplo
prueba :
function Foo() { }
var bar = new Foo()
// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true
// bar is an instance - it does not know how to create objects
bar.prototype // => undefined
¡¡¡ESTA ES LA MEJOR EXPLICACIÓN DEL MUNDO !!!!!
var q = {}
var prototype = {prop: 11}
q.prop // undefined
q.__proto__ = prototype
q.prop // 11
en los constructores de funciones, el motor javascript lo llama q.__proto__ = prototype
automáticamente cuando escribimos new Class
, y en el __proto__
conjunto de propiedadesClass.prototype
function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new
var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999
Disfrutar%)
''use strict''
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log(''=====''); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true
En JavaScript, cada objeto (¡la función también es un objeto!) Tiene una propiedad __proto__
, la propiedad es una referencia a su prototipo.
Cuando usamos el new
operador con un constructor para crear un nuevo objeto, la propiedad __proto__
del nuevo objeto se configurará con la propiedad prototype
del constructor, luego el nuevo objeto llamará al constructor, en ese proceso "esto" será una referencia a the new object in the constructor scope, finally return the new object.
El prototipo del constructor es __proto__
propiedad, la prototype
propiedad del constructor es trabajar con el new
operador.
El constructor debe ser una función, pero la función no siempre es un constructor, incluso si tiene prototype
propiedad.
La cadena de prototipos en realidad es __proto__
propiedad del objeto para hacer referencia a su prototipo, y la __proto__
propiedad del prototipo para hacer referencia al prototipo del prototipo, y así sucesivamente, hasta hacer referencia a la __proto__
propiedad del prototipo del Objeto que es referencia a nula.
Por ejemplo:
console.log(a.constructor === A); // true
// "a" don''t have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A
[[Prototype]]
Y la __proto__
propiedad en realidad es lo mismo.
Podemos usar el método getPrototypeOf de Object para obtener el prototipo de algo.
console.log(Object.getPrototypeOf(a) === a.__proto__); // true
Cualquier función que escribimos puede usarse para crear un objeto con el new
operador, por lo que cualquiera de esas funciones puede ser un constructor.
__proto__
es el objeto real que se usa 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;
__proto__
es la base para construir un prototype
y una función constructora, por ejemplo: function human(){}
tiene un prototype
que se comparte a través de __proto__
en la nueva instancia de la función constructora. Una lectura más detallada here
prototype
es una propiedad de un objeto de función. Es el prototipo de los objetos construidos por esa función.
__proto__
es propiedad interna de un objeto, que apunta a su prototipo. Los estándares actuales proporcionan un método Object.getPrototypeOf(O)
equivalente, aunque el estándar de facto __proto__
es más rápido.
Puede encontrar instanceof
relaciones comparando el prototype
una función con la cadena __proto__
un objeto, y puede romper estas relaciones cambiando el 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) de manera procesal. myPoint
es un objeto construido por Point()
por lo que Point.prototype
se guarda en myPoint.__proto__
en ese momento.
Prototype o Object.prototype es una propiedad de un objeto literal. Representa el objeto prototipo Objeto que puede reemplazar para agregar más propiedades o métodos a lo largo de la cadena del prototipo.
__proto__ es una propiedad de acceso (función obtener y establecer) que expone el prototipo interno de un objeto a través del cual se accede.
Referencias:
¿Qué pasa con el uso __proto__
de métodos estáticos?
function Foo(name){
this.name = name
Foo.__proto__.collection.push(this)
Foo.__proto__.count++
}
Foo.__proto__.count=0
Foo.__proto__.collection=[]
var bar = new Foo(''bar'')
var baz = new Foo(''baz'')
Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined
(function(){
let a = function(){console.log(this.b)};
a.prototype.b = 1;
a.__proto__.b = 2;
let q = new a();
console.log(a.b);
console.log(q.b)
})()
Intenta este código para entender
La propiedad proto es una propiedad de acceso simple en Object.prototype que consiste en una función getter y setter. Un acceso de propiedad para proto que finalmente consulta Object.prototype encontrará esta propiedad, pero un acceso que no consulte Object.prototype no lo encontrará. Si se encuentra alguna otra propiedad proto antes de consultar Object.prototype, esa propiedad ocultará la que se encuentra en Object.prototype.
La función proto getter expone el valor de la [[Prototype]] interna de un objeto. Para los objetos creados con un objeto literal, este valor es Object.prototype. Para los objetos creados con matrices literales, este valor es Array.prototype. Para las funciones, este valor es Function.prototype. Para los objetos creados con nueva diversión, donde la diversión es una de las funciones constructoras integradas que proporciona JavaScript (Array, Booleano, Fecha, Número, Objeto, Cadena, etc., incluidos los nuevos constructores agregados a medida que JavaScript evoluciona), este valor es siempre fun.prototype. Para los objetos creados con nueva diversión, donde diversión es una función definida en un script, este valor es el valor de fun.prototype. (Es decir, si el constructor no devolvió otro objeto explícitamente, o si se ha reasignado el fun.prototype desde que se creó la instancia).
El proto setter permite la mutación del [[Prototipo]] de un objeto. El objeto debe ser extensible de acuerdo con Object.isExtensible (): si no lo es, se lanza un TypeError. El valor proporcionado debe ser un objeto o nulo. Proporcionar cualquier otro valor no hará nada.
Para comprender cómo se utilizan los prototipos para la herencia, consulte el artículo de la guía Herencia y la cadena del prototipo.
Mi comprensión es: __proto__ y el prototipo se sirven para la técnica de la cadena de prototipos. la diferencia es que las funciones nombradas con un guión bajo (como __proto__) no están dirigidas a los desarrolladores invocados explícitamente. en otras palabras, son solo para algunos mecanismos como heredar, etc., son ''back-end''. pero las funciones nombradas sin subrayado están diseñadas para ser invocadas explícitamente, son "front-end".