Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Маленький тест ("конфлик" имён) (https://javascript.ru/forum/misc/5329-malenkijj-test-konflik-imjon.html)

Dmitry A. Soshnikov 05.10.2009 13:27

Маленький тест ("конфликт" имён)
 
Только что в одной news-группе спрашивали, почему код (см. ниже) вызывает "конфликт" имён?

<html>
<head>
    <title>Test</title>
    <script type="text/javascript">
        function test() {
            alert("Test");
        }
    </script>
</head>
<body>
    <form>
        <input type="button" name="test" onclick="test();" value="Test" />
    </form>
</body>
</html>


Данный код вызывает "test" is not a function. Очевидно завязанное имя элемента - это данность, вопрос в том, почему именно так?

P.S. этот небольшой тест развивает/определяет понимание механизма самого JS.

Zeroglif 05.10.2009 13:49

Подсказка, вместо :
onclick="test();"

вставим:
onclick="alert([type,elements,body,window])"

tenshi 05.10.2009 14:05

пипец 0_0 по ходу дела оно эквивалентно:
input.onclick= function(){
  with( this.form ){
    with( this ){
       alert( test )
    }
  }
}

Zeroglif 05.10.2009 14:11

tenshi,

document забыл... туда же...

Dmitry A. Soshnikov 05.10.2009 14:21

tenshi, если представить образно псевдо-кодом, мысль в правильном направлении. Подождём ещё ответов. Возможно, будет конкретный и точный.

Zeroglif, с подсказкой легче стало, ну да ладно =)

Dmitry A. Soshnikov 05.10.2009 21:23

Ну что, никаких предположений даже? Куда подевались все активные участники форума?

Kolyaj 05.10.2009 22:01

Ждем откровений. Я с этим сталкивался, но копать не стал. Точнее не я сталкивался, а здесь вопрос подобный задавали.

Zeroglif 05.10.2009 22:50

Dmitry A. Soshnikov,

неактивные уже отметились типа меня... пиши уж )

Dmitry A. Soshnikov 06.10.2009 00:17

Цитата:

Сообщение от Zeroglif
неактивные уже отметились типа меня

Да ладно, я сам очень редко создаю темы (наверное, всего третья за всё время) ;) Эта просто поинтересней была.

Цитата:

Сообщение от Kolyaj
Ждем откровений.

Цитата:

Сообщение от Zeroglif
пиши уж )

Ну ладно, раз больше никто не хочет высказать свои предположения...

Большинство (включая меня ;)) в первую секунду подумали, что вопрос простецкий и связан с IE (тот случай, когда IE маппит id-шники в глобальную область). Но нет, данное поведение воспроизводится во всех браузерах (к тому же, задан атрибут "name", а не "id").

Но в отладчике всё быстро прояснилось.

Дело связано с наличием формы. Функция, создаваемая из кода атрибута "onclick", порождается в контексте, scope chain которого содержит объект input-a и объект-формы. Соответственно, весь этот scope chain запоминается в onclick-функцию свойством [[Scope]]. Далее, при активации функции, создаётся её собственный Scope chain (AO контекста + [[Scope]]), где и происходит разрешение имён идентификаторов.

Если вставить вызов отладчика

<input ... onclick="debugger; alert(test === this);" />


и посмотреть Scope chain контекста, то мы увидим там пять объектов:

0. Call event=Event click
1. input Test
2. form (где |test| - это input-элемент)
3. Document
4. Window (где |test| - это глобальная функция)


Ну, а разрешение имени происходит из самого глубокого звена цепи, и вверх. Соответственно, имя test будет найдено на (3)-ем шаге, в пункте (2), т.е. в объекте формы, и значением будет является input-элемент.

Если удалить форму, то ошибки не будет (т.е. атрибут name может свободно называться, как функция), т.к. в Scope chain-e не будет формы, и имя test будет разрешено в глобальном объекте.

P.S.> Оригинальный вопрос и ответ в c.l.js - http://groups.google.ru/group/comp.l...11199a44?hl=en

Zeroglif 06.10.2009 00:25

Ещё от создателя, храню.

http://groups.google.com/group/netsc...4cb3c6af9c38c2


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