Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выполнение кода функции и кода eval. Gecko vs all others 
:(
    Опции темы
AKS
Дата 12.9.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



По мотивам этой темы решил написать немного своих наблюдений. Суть в том, что поведение Gecko оличается от остальных (IE6, Opera 7+, Safari 3 Win).
Итак, в этом случае во всех упомянутых браузерах все одинаково:
Код

// global code
var x = 0;

eval('function x() {}');

alert(x); // -> function x() {}

Если тоже самое выполнить в коде функции, то результат во всех браузерах будет тем же, но вот в Gecko он будет отличаться:
Код

function f() {

    var x = 0;

    eval('function x() {}');
    
    return x;
    
};

alert(f()); // -> 0 (Gecko)

Получается так, что Gecko в коде функции пытается "эмулировать" объявление именованной функции. А поскольку именованные функции становятся св-вами variable object раньше, чем объявляются локальные переменные, идентификатор функции (уже св-во variable object), должен быть "переписан" одноименным идентификатором локальной переменной. 
С тем, что происходит в коде функции я как-то разобрался (точнее сказать, "притянул" это к определенным фрагментам спецификации), а вот как быть с глобальным кодом? Почему в нем Gecko ведет себя иначе?
Кто-нибудь что-нибудь подобное уже "разбирал по полочкам"?

Это сообщение отредактировал(а) AKS - 12.9.2007, 13:01
PM MAIL   Вверх
Zeroglif
Дата 12.9.2007, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



На мой взгляд Mz, наоборот, делает всё правильно (в соответствии с ES) в глобальном контексте и неправильно в контексте функции f. Значением x должна стать функция.
PM MAIL WWW   Вверх
dsCode
Дата 12.9.2007, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



AKS, действительно. Интересная тема.. надо будет поискать в чем тут дело..

Предположения: ... в первом случае понятно, что eval(...) приводит к тому, что и x и x() становятся пропертями объекта window -  соотвественно, второе определение заменяет первый x. А вот во втором.... Хм... локальные переменные создаются в стеке.. Здесь они не объекты чего-то (хотя, "конечно", объекты, но точно ЧЕГО - не скажу сейчас). И в фаере ситуация происходит в обратном порядке... eval затирается объявлением переменной.


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
AKS
Дата 12.9.2007, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Zeroglif, т.е. не стоит называть это "попыткой эмулировать объявление именованной функции (FD)"?

Цитата(Zeroglif @  12.9.2007,  14:01 Найти цитируемый пост)
Значением x должна стать функция. 

Вот казалось бы именно так и должно было быть, но...
Если у variable object уже есть такое св-во, причем именно с атрибутом { DontDelete }, то изменить значение и атрибуты не получается. Если будут empty property attributes (т.е. идентификатор "пришел" в variable object из eval), то заменить может...


Цитата(dsCode @  12.9.2007,  14:46 Найти цитируемый пост)
.. локальные переменные создаются в стеке.. Здесь они не объекты чего-то (хотя, "конечно", объекты, но точно ЧЕГО - не скажу сейчас). И в фаере ситуация происходит в обратном порядке... eval затирается объявлением переменной. 

Локальные переменные становятся св-вами variable object (10.1.3 Variable Instantiation). И здесь скорее не "затирание", а просто отсутствие возможности как-раз сделать наоборот - т.е. изменить значение уже созданной property... 
PM MAIL   Вверх
Zeroglif
Дата 12.9.2007, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



Цитата(AKS @  12.9.2007,  17:22 Найти цитируемый пост)
т.е. не стоит называть это "попыткой эмулировать объявление именованной функции (FD)"?

"попытка эмулировать" - лишнее...

Цитата(AKS @  12.9.2007,  17:22 Найти цитируемый пост)
Если будут empty property attributes (т.е. идентификатор "пришел" в variable object из eval), то заменить может...

Да, я это тоже стразу проверил, взаимосвязь есть, но неизвестно какая..., возможно атрибут мешает (в глобальном контексте же не мешает), а может чего ещё. Я всё-таки склоняюсь к тому, что это баг (eval  же в Mz непростой, типа "двухконтекстный"). При разборе строки функция создаётся, порядок конкретизации не нарушен, можно делать с функцией что угодно, но вот при возврате в контекст функции мы по-прежнему имеем старое значение нужного свойства.


PM MAIL WWW   Вверх
AKS
Дата 12.9.2007, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(Zeroglif @  12.9.2007,  16:42 Найти цитируемый пост)
eval  же в Mz непростой, типа "двухконтекстный"

Двухконтекстный? Вы имеете ввиду, что можно опционально задать контекст:
Код

var a = { x: 0 };

eval('x = 10', a);

alert(a.x); // -> 10 (Gecko only)


PM MAIL   Вверх
Zeroglif
Дата 12.9.2007, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



Цитата(AKS @  12.9.2007,  18:07 Найти цитируемый пост)
можно опционально задать контекст

Я скорее про deprecated, но пока ещё работающую конкретную конструкцию window.eval, когда ни по форме записи, ни по наличию дополнительных аргументов нельзя определить, что это расширение JavaScript, работающее вне стандарта.
PM MAIL WWW   Вверх
AKS
Дата 12.9.2007, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Zeroglif, ага, понятно. 

PM MAIL   Вверх
dsCode
Дата 12.9.2007, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 565
Регистрация: 8.9.2007
Где: Saint-Petersburg

Репутация: 19
Всего: 26



AKS
Цитата(AKS @  12.9.2007,  16:22 Найти цитируемый пост)
Локальные переменные становятся св-вами variable object (10.1.3 Variable Instantiation). И здесь скорее не "затирание", а просто отсутствие возможности как-раз сделать наоборот - т.е. изменить значение уже созданной property... 


да.. проперти variable object... и по идее-то, одноименную проперть в объекте должны были перезаписать.. Странно... А как поступает eval(...) в данном случае? eval(...) тоже функция и тоже имеет формальный параметр - значит правила с variable object для нее тоже действуют. Если убрать eval(...)

Код

function f() {
    var x = 3;
    function x() {alert(1);};
    alert(x.toString());
};


мы получим тот же результат, но теперь и IE так же. Поясните, если можно, еще пару вещей: вот так вот объявленная функция x() разве не становится свойством variable object функции f? Для каждой функции создается свой variable object (далее VO)? Если функция x() не становится такми образом проперью VO, тогда eval(...) в FF работает правильно внутри функции. А в IE нет =) Или нет? Если написать так:

Код

function f() {
    var x = 3;
    var x = function () {alert(1);};
    alert(x.toString());
};

Тогда "эмулируется" ситуация IE. Ну здесь-то понятно, что x становится сво-ом VO. А вот, когда функция объявляется внутри функции, как в первом коде - что происходит? - Добавляется ли она в VO родительской функции как свойство (и тогда, ожидаемо, должна бы затереть существующий ключ хэша VO)? Или же все-таки добавляется, но не в ту область, где хранятся формальные параметры и локальные переменные функции?


--------------------
the .code inside
:my music
PM MAIL WWW ICQ Jabber   Вверх
Zeroglif
Дата 12.9.2007, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



Цитата(dsCode @  12.9.2007,  18:47 Найти цитируемый пост)
А вот, когда функция объявляется внутри функции, как в первом коде - что происходит?

В процессе конкретизации переменных (Variable Instantiation) :

1) VO.x = function-value
2) объявление переменной игнорируется*

При построчном разборе:

3) VO.x = 3

*Объявление переменной (var x) будет проигнорировано, т.к. свойство/слот с именем x уже существует (создана функция). В этом смысле объявленные функции сильнее объявленных переменных, они не дают себя "затереть" значением undefined, если функция заняла слот, то сдвинуть её оттуда можно только положив в этот слот новое значение, что и происходит, была функция, а стало число три...



Это сообщение отредактировал(а) Zeroglif - 12.9.2007, 18:22
PM MAIL WWW   Вверх
AKS
Дата 12.9.2007, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



А вот еще один "сюрприз" от Gecko:
Код

function f() {

    var x = 0;
    
    eval('function x() {}'); 
    
    function check() {
        return typeof x;
    };

    return [check, check()];
    
};

alert([f()[0](), f()[1]]); // -> number, function (Gecko) vs function, function (others) 

Получается, что все же внутри функции x становится функцией! А еще интересней, что вызвать ее нельзя напрямую, можно лишь "обернув" в другую функцию:
Код

(function () {

    var x = 0;
    
    eval('function x() { alert("X!"); }'); 
    
    function check() {
        return x();
    };

    // x(); -> error 
    
    check(); // calls function x and returns its result
    
})();

PM MAIL   Вверх
Zeroglif
Дата 12.9.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



Цитата(AKS @  12.9.2007,  20:46 Найти цитируемый пост)
Получается, что все же внутри функции x становится функцией!

Мрак. Определённо кривое поведение. Функция видна:

- у себя дома (при разборе строки в контексте eval);
- во вложенных функциях;

То есть во всех контекстах кроме того, где вызывается eval. Напишите в багзиллу, заодно узнаем, не постил ли кто раньше про такую же бяку. Или придётся надеяться на завсегдатаев c.l.j.

PM MAIL WWW   Вверх
AKS
Дата 12.9.2007, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Цитата(Zeroglif @  12.9.2007,  20:32 Найти цитируемый пост)
Напишите в багзиллу...

Я еще никогда никуда не писал рапорты, но завтра после обеда попытаюсь...

PM MAIL   Вверх
AKS
Дата 12.9.2007, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Участник форума
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 20.9.2006

Репутация: 27
Всего: 52



Zeroglif, сейчас посмотрел - уже сегодня отрапортовали. Но совсем в ином контексте! Вообще там ерунда получилась!

Добавил я там свой "отчет". Оказалось, что там сегодня  оставили еще один (а может и не один) такой же рапортsmile

Это сообщение отредактировал(а) AKS - 12.9.2007, 21:32
PM MAIL   Вверх
cruelangel
Дата 12.9.2007, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 319
Регистрация: 12.9.2007

Репутация: 4
Всего: 8



ещё один камень в пользу var x= function() smile
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1056 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.