Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Про ecmaScript (https://javascript.ru/forum/misc/24023-pro-ecmascript.html)

Иваннн 19.12.2011 14:16

Продолжение беседы
 
Почему так получается:
function f(){
this.a=1
}
fo=new f();
alert(fo.constructor.prototype===fo.constructor.prototype.constructor.prototype) // true

И в то же время:
alert(fo.b) //undefined (хотя согласно  определению внутреннего метода [[GetProperty]] в ecmaScript5.1  поиск свойвства с именем b заканчивается только тогда, когда свойвство [[prototype]]   становится null , что смотря на первый пример не случится никогда.

Livanderiaamarum 19.12.2011 14:34

Цитата:

Сообщение от Иваннн (Сообщение 144447)
Почему так получается:
function f(){
this.a=1
}
fo=new f();
alert(fo.constructor.prototype===fo.constructor.prototype.constructor.prototype) // true

И в то же время:
alert(fo.b) //undefined (хотя согласно  определению внутреннего метода [[GetProperty]] в ecmaScript5.1  поиск свойвства с именем b заканчивается только тогда, когда свойвство [[prototype]]   становится null , что смотря на первый пример не случится никогда.

свойство [[prototype]] это не свойство prototype


их часто путают, свойство [[prototype]] в javascript имеет вид __proto__
именно это вы и путаете.

а свойство prototype же вообще означает СОВСЕМ ДРУГОЕ(не смотря на похожие названия) типа "тут хранить методы которые будут доступны ДЕТЯМ объекта."

почему эти методы не засунуть в самого родителя, а засовывать в его свойство prototype? спросите вы? ну я думаю что так сделали чтобы не засирать радителя методами детей и.т.п. и в нем создали типа папочку prototype , в которой ДЕТИ этого обьекта и будут искать свои методы)) как то так

______________________
И еще скажу, на заметку. В том что вы щас читаете ВНУТРЕННИЕ МЕТОДЫ (то есть недоступные программисту, пишутся с двойными квадратными скобками по бокам, то есть по задумке свойство [[prototype]] или по русски __proto__ НЕ ДОСТУПНЫ В КОДЕ, это внутренние методы языка это для создателей движков написано. Но создатели движков сжалились над нами и сделали свойство [[prototype]] ДОСТУПНЫМ нам в коде и назвали его __proto__, это НЕ по спецификации, но так больше возможностей , его даже можно вручную изменять и.т.п. ) , да , а название у него сменили потому что квадратные скобки интерпретатор не правильно поймет.

Nekromancer 19.12.2011 14:45

Иваннн,
Я вот не понимаю, чего вы хотите этим добиться, доказать что спецификация неправильная или что?
Не знаю даже как вам объяснить, конкретный пример в спецификации сейчас искать не хочется.
Я вот хотел вам сейчас рассказать как строится всё архитектура пространства в JavaScript, но вовремя увидел, что вы уж совсем намудрили.
fo.constructor.prototype===fo.constructor.prototyp e.constructor.prototype
Это тоже самое что
fo.constructor.prototype === fo.constructor.prototype
Естественно тут замкнутый круг, вы здесь ни разу не идёте по цепочке прототипов, а просто по кругу - от прототипа конструктора, к самому конструктору и опять по новой.
Правильная цепочка прототипов выглядит так:
alert((function(){}).prototype.__proto__ === Object.prototype) // true

alert(Object.prototype.__proto__)

В общем вы путаете свойство prototype у конструктора и свойства __proto__ у объекта, которое как раз и указывает на свойство prototype конструктора. В следствии чего __proto__.__proto__ будет указывать на родительский прототип. А __proto__.constructor.prototype указывает на само себя.

Иваннн 19.12.2011 14:46

Да вроде не путаю.
 
Как раз я обращаюсь к [[prototype]] созданного объекта, и к его [[prototype]] Т.к. fo.__proto__===fo.constructor.prototype можно так написать последнее выражение:
alert(fo.__proto__===fo.__proto__.__proto__) и будет True
А по поводу самого свойвства prototype - в спецификации 5.1 явно указано что там хранится ссылка на объект, выражаясь Вашими терминами, "родитель" (прототип) объекта fo.

Nekromancer 19.12.2011 14:48

var a = function(){},
fo = new a();
alert(fo.__proto__===fo.__proto__.__proto__) //false

Будьте внимательнее.

Иваннн 20.12.2011 12:41

Спасибо все понял.
 
У меня было два заблуждения:
1)что цепочка прототипов это не только __proto__.__proto__..и т.д., но и constructor.prototype. Обратное мне пытались сказать Некромансер и др., но я не догонял. Меня сбило с толку равенство объект.__proto__===объект.constructor. prototype ( True причем не всегда, смотри второе заблуждение). Оказывается что перейти на прототип выше (по прототипной цепочке) можно исключительно через неявное свойвство объекта [[prototype]] ( в некоторых браузерах- явная ссылка __proto__). Согласно спецификации при создании объекта функции(далее F) создается свойвство объекта функции prototype, которое ссылается на обект ( далее Р), свойвства которого будут унаследованы объектом, создаваемым указанной функцией F (допустим при использовании оператора new F()). Но в процессе создания нашей функции (F) у объекта Р создается свойвство (собственное) constructor.
Это свойвство как раз и ссылается на нашу функцию F. Получается замкнутый круг :P.constructor.prototype===P(-true при не изменении значения свойвства prototype ).
2) я упустил из виду, что свойвство constructor для объекта, построенного с помощю нашей функции F (пусть будет О) не родное свойвство, а наследуемое. А кто следующий в цепочке? O.__proto__- в нем то и содержится родное свойвство constructor.
После изменения свойвства конструктора F.prototype с дефаултного на любой другой объект (т.е. изменения прототипа создаваемого объекта О), при вызове O.constructor это свойвсто c именем constructor будет искатся в нем (в О), потом при отсутсвии в O.__proto__, знечение которого уже не старый прототип P, а новый подставленный объект.

Все это хорошо описано на данном сайте в разделе обучение (Lern((как-то так).javascript.ru) а я написал все это для того чтобы мне ответили правильно ли я всю эту кухню понял. Отдельное спасибо Некромансеру за терпение.


Часовой пояс GMT +3, время: 11:53.