Соотношение переменных a.__proto__ и b

В коде присутствует

let a= new b();

Из этого равенства следует, что a - это экземпляр типа b (b является функцией-конструктором, заполняющей поля создаваемого объекта, экземпляром которого (объекта) является a), т. к. создана с помощью new и функции-конструктора b (если следовать по определению - см. new

Другими словами, вызов new User(...) делает примерно вот что:

function User(name) {
  //this={} (неявно)
  
  //добавляет свойства к this
  this.name = name;
  this.isAdmin = false;

  // return this;  (неявно)
}

То есть, результат вызова new User("Вася") – это тот же объект, что и:

let user={
  name: "Вася";
  isAdmin: false
}

). С другой стороны a.__proto__=b.prototype, т. е. a прототипно наследует b.prototype. Т. е. получаем, что a наследует b и a наследует b.prototype (прототипно). Это так? a наследует b?

P.S. a наследует b означает, что a получает поля от b.


Ответы (2 шт):

Автор решения: vsemozhebuty

Если вы имеете в виду прототипное наследование, то а не наследует b, иначе оно бы наследовало все свойства, которые есть у самой функции как объекта:

function b() {}
b.prototype.foo = 42;

let a = new b();

console.log(b.name); // b
console.log(a.name); // undefined

console.log(a.foo); // 42

Экземпляр протототипно наследует только от b.prototype.

Можно сказать, что b исполняет две функции: конструктора экземпляра и хранителя прототипа экземпляра в свойстве .prototype.

Или можно сказать, что в цепочке прототипов экземпляра есть b.prototype, но нет самой b. Она, как функция, создаёт экземпляр, но потом сама по себе не служит для него источником никаких свойств или методов, источником служит только b.prototype.

Всё зависит от того, что вы понимаете под наследованием. Если отношения создателя и создания, тогда можно сказать, что a наследует b, но это будет не очень в стиле JS — ведь в JS можно создать объекты с прототипным наследованием и без конструкторов или классов. Под наследованием лучше понимать связь через цепочку прототипов, то есть отношения объекта и прототипа, а не создателя и создания.

→ Ссылка
Автор решения: Qwertiy
//this={} (неявно)

Нет. Для функций и для классов без наследования так:

this = Object.create(User.prototype)
// return this;  (неявно)

В общем случае нет, но в приведённом примере - да.

То есть, результат вызова new User("Вася") – это тот же объект, что и:

Нет. На самом деле так:

let user = Object.create(User.prototype)
user.name = "Вася"
user.isAdmin = false

Если знать, что у User в прототипе нет сеттеров для name и isAdmin, то можно упростить:

let user = {
  __proto__: User.prototype,
  name: "Вася",
  isAdmin: false,
}

Наследование классов/функций означает, что созданный или объект прототипно наследует их prototype (т. е. он содержится в цепочке прототипов):

var pr = {}
var obj = Object.create(pr)

function F() {}
console.log(obj instanceof F)

F.prototype = pr
console.log(obj instanceof F)

var obj2 = Object.create(obj)

function G() {}
G.prototype = obj

console.log(obj2 instanceof G, obj instanceof G)
console.log(obj2 instanceof F, obj instanceof F)

F.prototype = {}
console.log(obj2 instanceof G, obj instanceof G)
console.log(obj2 instanceof F, obj instanceof F)

→ Ссылка