Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.08.2018, 02:02
Новичок на форуме
Отправить личное сообщение для Leonid_ts Посмотреть профиль Найти все сообщения от Leonid_ts
 
Регистрация: 27.08.2018
Сообщений: 6

Работа instanceof и цепочка прототипов
Всем привет! Изучаю js, читая Флэнагана и вот я наткнулся на мозговыносящий мне момент, связанный с цепочкой прототипов и работой instanceof.

В подробном руководстве Флэнагана написано "Чтобы вычислить значение выражения o instan­ce­of f, интерпретатор JavaScript определяет значение f.prototype и затем пытается отыскать это значение в цепочке прототипов объекта o. В случае успеха объект o считается экземпляром класса f"

Затем пробую выполнить следующую задачу:
создать объект с, котрый будет наследником объекта b, который является наследником объекта а. При этом эти объекты создаются при помощи соответствующих конструкторов (new A(), new B(), new C()).
получается следующий код:
function A() {
    this.a = 'a';
}

function B() {
    this.b = 'b';
}

function C() {
    this.c = 'c';
}

let a = new A();

B.prototype = a;

let b = new B();

C.prototype = b;

let c = new C()


В результате если ввести в консоль c, то в хроме нам выведет объект. И мое непонимание начинается, когда я смотрю прототипы этого объекта. Хром показывает:
C {c: "c"}
....c: "c"
....__proto__: A
........b: "b"
........__proto__: A
............a: "a"
............__proto__:
................constructor: f A()
................__proto__: Object

Так же если ввести в консоль C.prototype, то мы увидим следующее:
A {b: "b"}
....b: "b"
....__proto__: A
........a: "a"
........__proto__:
............constructor: f A()
............__proto__: Object

Везде в цепочке прототипов указан А и если мы введем в консоль c instanceof C, то резульататом будет true. НО! если мы введем а intanceof C, то результатом будет false. И казалось бы логично, ведь а построен конструктором А. Но ведь в книге сказано
"интерпретатор JavaScript определяет значение f.prototype и затем пытается отыскать это значение в цепочке прототипов объекта o. В случае успеха объект o считается экземпляром класса f"

Так почему a instanceof C будет false, если в консоли явно видно, что прототипом C является прототип А, и а имеет тот же самый прототип, что и С?

Буду благодарен как прямым ответам, так и ссылкам на подбробное разжевывание этого вопроса. На MDN ответа так и не нашел.

P.S. Доп. вопрос: почему если вписать в консоль c мы увидим C {c: "c"}, а если вписать b, то увидим не B {b: "b"}, a A {b: "b"}
Ответить с цитированием
  #2 (permalink)  
Старый 29.08.2018, 02:19
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

Если утрировать instanceof просто проходит по цепочке прототипов левого аргумента и проверяет на строгое равенство(===) с прототипом правого аргумента.
И это логично в рамках объектного наследования: c создан классом C - наследником от класса A, класс C связан с классом A цепочкой прототипов, потому c instanceof A === true, a же создан классом A - родителем по отношению C, класс A ничего не знает о классе C, он никак с ним не связан, и естественно a instanceof C === false.

А на "доп. вопрос" ответ: хром не угадал. Можешь запостить им баг.)
__________________
29375, 35

Последний раз редактировалось Aetae, 29.08.2018 в 02:30.
Ответить с цитированием
  #3 (permalink)  
Старый 29.08.2018, 02:25
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

intanceof поверяет принадлежность двигаясь к вершине иерархии пока не дойдет до Object, а не обследует все ветки, если он бы так делал его работа была бы бессмысленна.
Ответить с цитированием
  #4 (permalink)  
Старый 29.08.2018, 02:33
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Сообщение от Leonid_ts
Везде в цепочке прототипов указан А
Ну фигли, ты затер все конструкторы, кто же так наследует.
Ответить с цитированием
  #5 (permalink)  
Старый 29.08.2018, 13:13
Новичок на форуме
Отправить личное сообщение для Leonid_ts Посмотреть профиль Найти все сообщения от Leonid_ts
 
Регистрация: 27.08.2018
Сообщений: 6

Сообщение от Aetae Посмотреть сообщение
Если утрировать instanceof просто проходит по цепочке прототипов левого аргумента и проверяет на строгое равенство(===) с прототипом правого аргумента.
Спасибо, теперь понятно. Но остался вопрос. Почему хром в свойстве __proto__ в цепочке прототипов объекта с везде пишет A, а не B, затем A? Т.е. почему так

C {c: "c"}
....c: "c"
....__proto__: A
........b: "b"
........__proto__: A
............a: "a"
............__proto__:
................constructor: f A()
................__proto__: Object

а не так
C {c: "c"}
....c: "c"
....__proto__: B
........b: "b"
........__proto__: A
............a: "a"
............__proto__:
................constructor: f A()
................__proto__: Object

Ведь объекту С присвоен прототипом объект b, и только объекту B присвоен прототипом объект а.
Ответить с цитированием
  #6 (permalink)  
Старый 29.08.2018, 16:34
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

Как сказал выше Rise: ты затер все конструкторы.
В __ptoto__ объекта должна быть ссылка на функцию-конструктор данного объекта(создавшую его). Соответственно делая X.prototype = new Y; заменяешь прототип X по умолчанию (по сути такой {constructor: X, __proto__:Object.prototype }) на объект созданный Y, в котором нет свойства constructor.
Chrome в твоём случае для c соответственно смотрит в __proto__, не видит там constructor, лезет в __proto__.__proto__ смотрит там, не видит, смотрит в __proto__.__proto__.__proto__ и наконец находит первый коструктор, прототип для которого не менялся, сохранив сие свойство: A.
__________________
29375, 35

Последний раз редактировалось Aetae, 29.08.2018 в 16:41.
Ответить с цитированием
  #7 (permalink)  
Старый 29.08.2018, 20:19
Новичок на форуме
Отправить личное сообщение для Leonid_ts Посмотреть профиль Найти все сообщения от Leonid_ts
 
Регистрация: 27.08.2018
Сообщений: 6

Aetae,
благодарю! Теперь стало понятно. А можете, если не трудно, привести пример, как было бы правильно организовать подобную цепочку наследования? Спасибо!
Ответить с цитированием
  #8 (permalink)  
Старый 29.08.2018, 20:28
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

https://learn.javascript.ru/class-in...классах
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вакансия: Программист IOS, работа в офисе,г.Ростов-на-Дону Анна NikitaOnline Работа 0 21.03.2016 18:45
Постоянная работа / Front-end / Москва kooper Работа 4 29.09.2011 22:06
Вопрос про ООП, цепочки прототипов. Shaci Общие вопросы Javascript 5 27.01.2010 14:50