Головоломка-прототип с JavaScript - PullRequest
0 голосов
/ 14 октября 2018

Я не могу понять, почему следующий код выдает «Smith» в качестве вывода, а не «Smith Foo».Не могли бы вы уточнить, почему это происходит?Я не могу понять, как поиск свойства childFoo в цепочке прототипов находит путь к прототипу дочернего элемента.

var parent = {};
var child = Object.create(parent); 
Object.getPrototypeOf(parent).Surname = 'Smith';  

var parentFoo = function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);   
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';   

console.log(childFoo.Surname);
// this outputs 'Smith' only.

Ответы [ 3 ]

0 голосов
/ 14 октября 2018

Вы изменили прототип объекта Object, от которого наследуется каждый объект (если явно не указано), с помощью этой строки кода:

Object.getPrototypeOf(parent).Surname = 'Smith';  

Здесь мы можем увидеть devtools, который показывает, что вы к свойствуФамилия со значением Смита на прототипе Объекта.

enter image description here

Затем со следующей строкой кода:

Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo'; 

Youпоместите строку 'Smith Foo' в качестве свойства фамилии в прототипе функции.Вот как это выглядит в chrome devtools:

enter image description here

Вот что вы должны сделать, чтобы получить желаемый результат:

var parent = {};
var child = Object.create(parent);
Object.getPrototypeOf(parent).Surname = 'Smith';

var parentFoo = function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);   
// change parentFoo to childFoo
Object.getPrototypeOf(childFoo).Surname = 'Smith Foo';

console.log(childFoo.Surname);
0 голосов
/ 14 октября 2018

Вот окончательный ответ:

function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);   

parentFoo.__proto__.Surname = 'Smith Foo';   
console.log(childFoo.Surname);
console.log(parentFoo.__proto__);

parentFoo.__proto__.__proto__.Surname = 'Smith Foo';   
console.log(childFoo.Surname);
console.log(parentFoo.__proto__.__proto__);

Вот что я нашел:

  1. При непосредственном использовании функции конструктора и ключевого слова 'new' непосредственный прототип вашего нового объекта будетбыть специальным прототипом функции

    • и следующим в цепочке будет специальный прототип общего объекта.
  2. При непосредственном использовании функции конструктора и 'new'ключевое слово, непосредственным прототипом вашего нового объекта будет прототип специальной функции

    • , и этот прототип не имеет никакого отношения к самому прототипу функции.

Надеюсь, на этот раз я все понял :) Спасибо всем за помощь!

0 голосов
/ 14 октября 2018

Источником путаницы здесь, как мне кажется, является разница между getPrototypeOf(a) и a.prototype.

  • a.prototype - это прототип, который будет использоваться для создания экземпляров a, как в new a().
  • Object.getPrototypeOf(a) возвращает прототип, который использовался для создания a, как в a = new AClass().

Итак, когда вы делаете a = new AClass(), Object.getPrototypeOf(a) равен AClass.prototype, прототип, который использовался для создания a.

Object.getPrototypeOf(parent).Surname = 'Smith';

Здесь getPrototypeOf возвращает прототип, использованный для создания{}, что составляет Object.prototype.Эта строка эквивалентна Object.prototype.Surname = 'Smith'.

Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';

Здесь getPrototypeOf возвращает прототип, использованный для создания parentFoo, то есть function(){}: возвращаемое значение - Function.prototype.Эта строка эквивалентна Function.prototype.Surname = 'Smith Foo'.

console.log(childFoo.Surname);

childFoo - это экземпляр parentFoo, но parentFoo.prototype не был изменен, поэтому это пустой объект (кроме встроенных).Таким образом, childFoo.Surname идет вверх по цепочке прототипов, заканчиваясь Object.prototype - корнем, от которого наследуются все объекты JS.Вот где он находит свойство Surname, которое вы определили ранее, 'Smith'.

И если вы сделаете (function () {}).Surname, вы увидите строку 'Smith Foo', потому что она была определена в Function.prototype.

(Это может быть очень сложной частью JS, чтобы обернуть голову, так что я надеюсь, что это имеет смысл!)

...