onclick = оповещение (ping.test); дает неопределенное

<body>
   <script>
    ping = new Object;
    ping.test = '1234';
   </script>

<a href="#" onclick="alert(ping.test);">Test</a>
</body>

почему это работает в IE8, но не в Firefox или Chrome? Всплывающее окно выдает «undefined» в FF v5 и Chrome v12, оно выдает «1234» в IE9.


person Benjamin    schedule 08.07.2011    source источник
comment
Это должно сработать, хотя многое можно было бы улучшить.   -  person alex    schedule 08.07.2011
comment
Вы также должны указать тип скрипта: type=text/javascript   -  person Julien Ducro    schedule 08.07.2011
comment
Мистер Чиф, я использую FF5 и Chrome 12, и он не работает. Я делаю что-то незаконное?   -  person Benjamin    schedule 08.07.2011


Ответы (3)


Это вопрос масштаба. Попробуй это:

<body>
   <script>
    var ping = {};
    ping.test = '1234';
   </script>

<a href="#" onclick="alert(ping.test);">Test</a>
</body>

Изменить: это работает для меня

<body>
   <script>
    var ping = {};
    ping.test = '1234';

    function test(){
        alert(ping.test);
    }
   </script>
<a href="#" onclick="test();">Test</a>
</body>
person Ilia Choly    schedule 08.07.2011
comment
Илья, спасибо, но все еще есть undefined с Chrome V.12 и FF 5.0. - person Benjamin; 08.07.2011
comment
только что попробовал с var ping = {}; все равно FF5 дает undefined. Вы, ребята, думаете, что это ошибка в FF5 и Chrome 12? - person Benjamin; 08.07.2011
comment
Илья спасибо. Я буду использовать этот метод, так как он работает во всех браузерах. Я все еще немного не понимаю, что не так с передачей объекта в обработчик событий в FF5 или Chrome12. - person Benjamin; 08.07.2011
comment
здесь есть несколько хороших объяснений: stackoverflow.com/questions/224820/ - person Ilia Choly; 08.07.2011

Это встроенная модель событий (уровень DOM 0), поэтому будут использоваться только переменные, определенные в контексте ее выполнения.

Следующий раздел

ping = new Object;
ping.test = '1234';

находится в своем собственном контексте выполнения, когда интерпретатор просматривает страницу. Код в глобальной области видимости будет использовать глобальный объект через this.

Но здесь

<a href="#" onclick="alert(ping.test);">Test</a>

является отдельным выполнением, которое ваш браузер рассматривает как анонимную функцию. С использованием

<a href="#" onclick="alert(this);">Test</a>

Не приведет к тому, что мы хотим. Строка видит window, this на самом деле используется для текущего объекта, с которым работает встроенный обработчик событий.

Таким образом, ping не определяется в этом контексте, если только мы не позволим его увидеть, обратившись к window.

<a href="#" onclick="alert(window.ping.test);">Test</a>

Теперь, когда браузер запустится, он возьмет глобальную переменную window, которая в контексте (\script\) будет такой же, как this, и будет иметь доступ к ping.test.

Видно в следующих браузерах

  • Google Chrome Mac 12.0.742.112
  • Safari версии 5.0.5 (6533.21.1)
  • Firefox Mac 3.6.18

Ссылки
Документы Mozilla: это ключевое слово
Dom Events: встроенная модель

person phwd    schedule 08.07.2011

ping вышел за рамки. Попробуй это:

<body>
    <a href="#" id="test">Test</a>
    <script>
    var ping = new Object();
    ping.test = '1234';
    document.getElementById("test").onclick = function() { 
        alert(ping.test);
    };
    </script>
</body>
person Zach Rattner    schedule 08.07.2011
comment
как пинг выходит за рамки? в этот момент это глобальный объект. (кроме этого, я думаю, что ваш общий стиль кодирования намного лучше) - person Jim Deville; 08.07.2011
comment
если вы не объявляете переменную с помощью var, с областью действия происходят непредсказуемые вещи. - person Ilia Choly; 08.07.2011
comment
Спасибо, Зак, проблема в том, что мое приложение очень интенсивно использует AJAX. (использование функциональности jquery live - не лучший вариант) - person Benjamin; 08.07.2011
comment
Вам не нужно использовать JQuery в реальном времени, если вы повторно выберете свои объекты в своей функции обратного вызова AJAX, вы можете добиться того же эффекта. - person Zach Rattner; 08.07.2011
comment
если вы не объявляете с помощью var, это очень предсказуемо: переменная помещается в глобальный объект. Это часть спецификации JS - person Jim Deville; 08.07.2011
comment
@James Deville: Где в спецификации это сказано? не вижу на стр. 87–88, где описаны объявления переменных. (ecma-international.org/publications/files/ECMA -ST/Ecma-262.pdf) - person Zach Rattner; 08.07.2011
comment
@zach - если вы будете следовать спецификации от синтаксического анализа грамматики (11.13.1.1) до поиска ссылок (10.2.2.1) и внутреннего вызова PutValue (11.13.1.5->8.7.2), вы в конечном итоге либо попадете в строгий режим ( 8.7.2.3.a) или назначение с помощью операции [[Put]] на глобальном объекте (8.7.2.3.b) - person Jim Deville; 08.07.2011