[[Прототип]]:
[[Prototype]] - это внутреннее скрытое свойство объектов в JS и ссылка на другой объект. Каждый объект во время создания получает ненулевое значение для [[Prototype]]. Помните, что операция [[Get]] вызывается, когда мы ссылаемся на свойство объекта, например myObject.a. Если у самого объекта есть свойство a, то будет использовано это свойство.
let myObject= {
a: 2
};
console.log(myObject.a); // 2
Но если сам объект напрямую не имеет запрошенного свойства, тогда операция [[Get]] перейдет по ссылке [[Prototype]] объекта. Этот процесс будет продолжаться до тех пор, пока не будет найдено подходящее имя свойства или пока не завершится цепочка [[Prototype]] (во встроенном Object.prototype). Если подходящего свойства не найдено, будет возвращено значение undefined. Object.create (specifiedObject) создает объект со связью [[Prototype]] с указанным объектом.
let anotherObject= {
a: 2
};
// create an object linked to anotherObject
let myObject= Object.create(anotherObject);
console.log(myObject.a); // 2
Как цикл for..in, так и оператор in используют процесс поиска в цепочке [[Prototype]]. Итак, если мы используем цикл for..in для перебора свойств объекта, тогда все перечисляемые свойства, которые могут быть достигнуты через цепочку [[Prototype]] этого объекта, также будут перечислены вместе с перечисляемыми свойствами самого объекта. А при использовании оператора in для проверки наличия свойства у объекта оператор in будет проверять все свойства через связь [[Prototype]] объекта независимо от их перечислимости.
// for..in loop uses [[Prototype]] chain lookup process
let anotherObject= {
a: 2
};
let myObject= Object.create(anotherObject);
for(let k in myObject) {
console.log("found: " + k); // found: a
}
// in operator uses [[Prototype]] chain lookup process
console.log("a" in myObject); // true
.prototype:
.prototype - это свойство функций в JS и относится к объекту, имеющему свойство конструктора, в котором хранятся все свойства (и методы) объекта функции.
let foo= function(){}
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties
foo.id= "Walter White";
foo.job= "teacher";
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties and 2 more properties that we added to the fn object
/*
{constructor: f}
constructor: f()
id: "Walter White"
job: "teacher"
arguments: null
caller: null
length: 0
name: "foo"
prototype: {constructor: f}
__proto__: f()
[[FunctionLocation]]: VM789:1
[[Scopes]]: Scopes[2]
__proto__: Object
*/
Но обычные объекты в JS не имеют свойства .prototype. Мы знаем, что Object.prototype является корневым объектом всех объектов в JS. Итак, очевидно, что Object - это функция, то есть typeof Object === function. Это означает, что мы также можем создать объект из функции Object, например let myObj = new Object (). Точно так же Array, Function также являются функциями, поэтому мы можем использовать Array.prototype, Function.prototype для хранения всех общих свойств массивов и функций. Итак, мы можем сказать, что JS построен на функциях.
{}.prototype; // SyntaxError: Unexpected token '.'
(function(){}).prototype; // {constructor: f}
Также с помощью оператора new, если мы создаем объекты из функции, тогда внутреннее свойство hidden [[Prototype]] этих вновь созданных объектов будет указывать на объект, на который ссылается свойство .prototype исходной функции. В приведенном ниже коде мы создали объект a из fn, Letter и добавили 2 свойства: одно к объекту fn, а другое к объекту-прототипу fn. Теперь, если мы попытаемся получить доступ к обоим свойствам вновь созданного объекта, тогда мы сможем получить доступ только к свойству, добавленному к объекту-прототипу функции. Это связано с тем, что объект-прототип функции теперь находится в цепочке [[Prototype]] вновь созданного объекта, a.
let Letter= function(){}
let a= new Letter();
Letter.from= "Albuquerque";
Letter.prototype.to= "New Hampshire";
console.log(a.from); // undefined
console.log(a.to); // New Hampshire
.__proto__:
.__proto__
- это свойство объектов в JS, и оно ссылается на другой объект в цепочке [[Prototype]]. Мы знаем, что [[Prototype]] - это внутреннее скрытое свойство объектов в JS, и оно ссылается на другой объект в цепочке [[Prototype]]. Мы можем получить или установить объект, на который ссылается внутреннее свойство [[Prototype]], двумя способами.
Object.getPrototypeOf(obj) / Object.setPrototypeOf(obj)
obj.__proto__
Мы можем пройти по цепочке [[Prototype]], используя: .__proto__.__proto__. .
. Наряду с .constructor, .toString (), .isPrototypeOf () наше ужасное свойство proto (__proto__
) фактически существует во встроенном корневом объекте Object.prototype, но доступно для любого конкретного объекта. Наш .__proto__
на самом деле является геттером / сеттером. Реализация .__proto__
в Object.prototype приведена ниже:
Object.defineProperty(Object.prototype, "__proto__", {
get: function() {
return Object.getPrototypeOf(this);
},
set: function(o) {
Object.setPrototypeOf(this, o);
return o;
}
});
Получение значения obj.__proto__
похоже на вызов obj.__proto__()
, который фактически возвращает вызов метода получения fn, Object.getPrototypeOf(obj)
, который существует в объекте Object.prototype. Хотя .__proto__
является настраиваемым свойством, мы не должны изменять [[Prototype]] уже существующего объекта из-за проблем с производительностью.
Используя оператор new, если мы создаем объекты из функции, тогда внутреннее свойство hidden [[Prototype]] этих вновь созданных объектов будет указывать на объект, на который ссылается свойство .prototype исходной функции. Используя свойство .__proto__
, мы можем получить доступ к другому объекту, на который ссылается внутреннее скрытое свойство [[Prototype]] объекта. Но __proto__
- это не то же самое, что [[Prototype]], а скорее геттер / сеттер для него. Рассмотрим код ниже:
let Letter= function() {}
let a= new Letter();
let b= new Letter();
let z= new Letter();
// output in console
a.__proto__ === Letter.prototype; // true
b.__proto__ === Letter.prototype; // true
z.__proto__ === Letter.prototype; // true
Letter.__proto__ === Function.prototype; // true
Function.prototype.__proto__ === Object.prototype; // true
Letter.prototype.__proto__ === Object.prototype; // true
![введите описание изображения здесь](https://i.stack.imgur.com/6FF0v.png)
person
djbtalk
schedule
19.07.2020
__proto__
отличается отconstructor.prototype
? - person Bergi   schedule 15.03.2014