Маленький тест ("конфликт" имён)
Только что в одной 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. |
Подсказка, вместо :
onclick="test();" вставим: onclick="alert([type,elements,body,window])" |
пипец 0_0 по ходу дела оно эквивалентно:
input.onclick= function(){ with( this.form ){ with( this ){ alert( test ) } } } |
tenshi,
document забыл... туда же... |
tenshi, если представить образно псевдо-кодом, мысль в правильном направлении. Подождём ещё ответов. Возможно, будет конкретный и точный.
Zeroglif, с подсказкой легче стало, ну да ладно =) |
Ну что, никаких предположений даже? Куда подевались все активные участники форума?
|
Ждем откровений. Я с этим сталкивался, но копать не стал. Точнее не я сталкивался, а здесь вопрос подобный задавали.
|
Dmitry A. Soshnikov,
неактивные уже отметились типа меня... пиши уж ) |
Цитата:
Цитата:
Цитата:
Большинство (включая меня ;)) в первую секунду подумали, что вопрос простецкий и связан с 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 |
|
Часовой пояс GMT +3, время: 10:35. |