![]() |
Модераторы: Sardar, Aliance |
![]() ![]() ![]() |
|
AKS |
|
||||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
По мотивам этой темы решил написать немного своих наблюдений. Суть в том, что поведение Gecko оличается от остальных (IE6, Opera 7+, Safari 3 Win).
Итак, в этом случае во всех упомянутых браузерах все одинаково:
Если тоже самое выполнить в коде функции, то результат во всех браузерах будет тем же, но вот в Gecko он будет отличаться:
Получается так, что Gecko в коде функции пытается "эмулировать" объявление именованной функции. А поскольку именованные функции становятся св-вами variable object раньше, чем объявляются локальные переменные, идентификатор функции (уже св-во variable object), должен быть "переписан" одноименным идентификатором локальной переменной. С тем, что происходит в коде функции я как-то разобрался (точнее сказать, "притянул" это к определенным фрагментам спецификации), а вот как быть с глобальным кодом? Почему в нем Gecko ведет себя иначе? Кто-нибудь что-нибудь подобное уже "разбирал по полочкам"? Это сообщение отредактировал(а) AKS - 12.9.2007, 13:01 |
||||
|
|||||
Zeroglif |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
На мой взгляд Mz, наоборот, делает всё правильно (в соответствии с ES) в глобальном контексте и неправильно в контексте функции f. Значением x должна стать функция.
|
|||
|
||||
dsCode |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
AKS, действительно. Интересная тема.. надо будет поискать в чем тут дело..
Предположения: ... в первом случае понятно, что eval(...) приводит к тому, что и x и x() становятся пропертями объекта window - соотвественно, второе определение заменяет первый x. А вот во втором.... Хм... локальные переменные создаются в стеке.. Здесь они не объекты чего-то (хотя, "конечно", объекты, но точно ЧЕГО - не скажу сейчас). И в фаере ситуация происходит в обратном порядке... eval затирается объявлением переменной. |
|||
|
||||
AKS |
|
|||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif, т.е. не стоит называть это "попыткой эмулировать объявление именованной функции (FD)"?
Вот казалось бы именно так и должно было быть, но... Если у variable object уже есть такое св-во, причем именно с атрибутом { DontDelete }, то изменить значение и атрибуты не получается. Если будут empty property attributes (т.е. идентификатор "пришел" в variable object из eval), то заменить может... Локальные переменные становятся св-вами variable object (10.1.3 Variable Instantiation). И здесь скорее не "затирание", а просто отсутствие возможности как-раз сделать наоборот - т.е. изменить значение уже созданной property... |
|||
|
||||
Zeroglif |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
"попытка эмулировать" - лишнее...
Да, я это тоже стразу проверил, взаимосвязь есть, но неизвестно какая..., возможно атрибут мешает (в глобальном контексте же не мешает), а может чего ещё. Я всё-таки склоняюсь к тому, что это баг (eval же в Mz непростой, типа "двухконтекстный"). При разборе строки функция создаётся, порядок конкретизации не нарушен, можно делать с функцией что угодно, но вот при возврате в контекст функции мы по-прежнему имеем старое значение нужного свойства. |
||||
|
|||||
AKS |
|
|||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
||||
|
||||
Zeroglif |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
||||
|
||||
AKS |
|
|||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
Zeroglif, ага, понятно.
|
|||
|
||||
dsCode |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 565 Регистрация: 8.9.2007 Где: Saint-Petersburg Репутация: 19 Всего: 26 |
AKS,
да.. проперти variable object... и по идее-то, одноименную проперть в объекте должны были перезаписать.. Странно... А как поступает eval(...) в данном случае? eval(...) тоже функция и тоже имеет формальный параметр - значит правила с variable object для нее тоже действуют. Если убрать eval(...)
мы получим тот же результат, но теперь и IE так же. Поясните, если можно, еще пару вещей: вот так вот объявленная функция x() разве не становится свойством variable object функции f? Для каждой функции создается свой variable object (далее VO)? Если функция x() не становится такми образом проперью VO, тогда eval(...) в FF работает правильно внутри функции. А в IE нет =) Или нет? Если написать так:
Тогда "эмулируется" ситуация IE. Ну здесь-то понятно, что x становится сво-ом VO. А вот, когда функция объявляется внутри функции, как в первом коде - что происходит? - Добавляется ли она в VO родительской функции как свойство (и тогда, ожидаемо, должна бы затереть существующий ключ хэша VO)? Или же все-таки добавляется, но не в ту область, где хранятся формальные параметры и локальные переменные функции? |
||||
|
|||||
Zeroglif |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
В процессе конкретизации переменных (Variable Instantiation) : 1) VO.x = function-value 2) объявление переменной игнорируется* При построчном разборе: 3) VO.x = 3 *Объявление переменной (var x) будет проигнорировано, т.к. свойство/слот с именем x уже существует (создана функция). В этом смысле объявленные функции сильнее объявленных переменных, они не дают себя "затереть" значением undefined, если функция заняла слот, то сдвинуть её оттуда можно только положив в этот слот новое значение, что и происходит, была функция, а стало число три... Это сообщение отредактировал(а) Zeroglif - 12.9.2007, 18:22 |
|||
|
||||
AKS |
|
||||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
А вот еще один "сюрприз" от Gecko:
Получается, что все же внутри функции x становится функцией! А еще интересней, что вызвать ее нельзя напрямую, можно лишь "обернув" в другую функцию:
|
||||
|
|||||
Zeroglif |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 644 Регистрация: 22.9.2005 Репутация: 28 Всего: 66 |
Мрак. Определённо кривое поведение. Функция видна: - у себя дома (при разборе строки в контексте eval); - во вложенных функциях; То есть во всех контекстах кроме того, где вызывается eval. Напишите в багзиллу, заодно узнаем, не постил ли кто раньше про такую же бяку. Или придётся надеяться на завсегдатаев c.l.j. |
|||
|
||||
AKS |
|
|||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
||||
|
||||
AKS |
|
|||
Участник форума ![]() ![]() Профиль Группа: Участник Сообщений: 725 Регистрация: 20.9.2006 Репутация: 27 Всего: 52 |
||||
|
||||
cruelangel |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 319 Регистрация: 12.9.2007 Репутация: 4 Всего: 8 |
ещё один камень в пользу var x= function()
![]() |
|||
|
||||
![]() ![]() ![]() |
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |