Является ли «чистый» зарезервированным словом в Javascript? - PullRequest
35 голосов
/ 23 августа 2011

Я потратил много времени на то, чтобы выяснить, что я не должен использовать clear () как имя функции в Javascript:

<head>
    <script type="text/javascript" src="Array.js"></script>
</head>
<body>
    Hello!!!!<br>
    <button type="button" onClick="clear()" id="ppp">Shoo!</button><br>
    <button type="button" onClick="add()" id="add">Add a few elements</button><br>
    <button type="button" onClick="check()" id="check">Check the array</button><br>
    <p id="results">Results will appear here.</p>
    <script type="text/javascript">
initialize();
    </script>
</body>

Вот Array.js:

var results;

function initialize(){
 results = document.getElementById("results");
}

function add() {
results.firstChild.data="add";    
}

function clear() {
results.firstChild.data = "Hello?";
}

function check() {
results.firstChild.data = "check";
}

Симптомы: нажатие кнопок «добавить» и «проверить» дает мне ожидаемый результат, но нажатие кнопки «очистить» ничего не дает.

Если я переименую clear () в clearxyz () , работает нормально.

Мои вопросы:

  1. Является ли "ясно" зарезервированным словом?Я не вижу его в списке: https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
  2. Есть ли уловка отладки, которую я должен использовать, чтобы выяснить подобные вещи в будущем?Мне потребовалось много времени (я нуб!), Чтобы понять, что имя функции было моей проблемой.

Большое спасибо.Изменить: я использую Firefox 6.0, и я добавил разрыв строки, чтобы показать, где начинается Array.js.

Ответы [ 4 ]

35 голосов
/ 23 августа 2011

Как говорили другие, clear - это , а не зарезервированное ключевое слово.Кажется, что вызываемая функция имеет вид document.clear [MDN] .Вызов

console.log(clear === document.clear);

внутри обработчика события возвращает true.

DEMO

Так что, похоже, document находится в цепочке областей действия обработчика событий .... теперь возникает вопрос:

JavaScript: полное руководство гласит:

ВОбработчик события как атрибут HTML, объект Document находится в цепочке областей действия перед объектом Window (...)

Поскольку ваш метод является глобальным, то есть он является свойством объекта window,он не найден в цепочке областей действия, так как document.clear находится раньше в цепочке областей действия.

Я не нашел никакой спецификации для этого.В руководстве также сказано, что на это не следует полагаться, поэтому я предполагаю, что это не является официальным документом.

Если у вас есть элементы формы внутри формы, то даже соответствующий элемент form будет находиться в цепочке областей действия (не уверен, правда ли это для всех браузеров).Это еще одна причина путаницы.


Существует два (не исключительных) способа избежать таких ситуаций:

  • Не использовать встроенное событиеобработчики. Это считается плохой практикой, поскольку смешивает логику и представление.Есть другие способы для подключения обработчиков событий.

  • Не загрязнять глобальное пространство имен. Создать один объектв глобальной области видимости (имя, в котором вы уверены, не вступает в противоречие с какими-либо window или document свойствами или идентификаторами элементов HTML), и назначьте функции в качестве свойств этого объекта.Всякий раз, когда вы вызываете функцию, вы ссылаетесь на нее через этот объект.Есть также другие способы для именования вашего кода.

2 голосов
/ 23 августа 2011

Хороший вопрос.Я думаю, что проблема - это ограниченная проблема - ваш onClick="clear()" не идет к функции clear, которую вы определили, но я не уверен, куда она идет.Изменение на window.clear() или новая функция, которая просто вызывает ваш clear, работает.

<body>
    Hello!!!!<br>
    <button type="button" onClick="clear()" id="ppp">Shoo!</button><br>
    <button type="button" onClick="window.clear()" id="ppp">window.clear!</button><br>
    <button type="button" onClick="clear2()" id="ppp">clear2!</button><br>
    <button type="button" onClick="add()" id="add">Add a few elements</button><br>
    <button type="button" onClick="check()" id="check">Check the array</button><br>
    <p id="results">Results will appear here.</p>
    <script type="text/javascript">
    var results;

function initialize(){
 results = document.getElementById("results");
}

function add() {
results.firstChild.data="add";    
}

function clear() {
results.firstChild.data = "Hello";
}

function clear2() {
clear();
}

function check() {
results.firstChild.data = "check";
}
initialize();
    </script>
</body>
2 голосов
/ 23 августа 2011

Не в соответствии с MDN .

Редактировать:

Вы меня заинтересовали, поэтому я бросил вместе этот маленький jsfiddle .

function clear() {
    alert("you cleared just fine");
}

$('clear').addEvent('click', clear);

Кажется, что функция с именем clear отлично работает.

1 голос
/ 12 ноября 2015

Нет, clear не является зарезервированным ключевым словом.

Проблема в том, что, поскольку вы используете атрибут содержимого обработчика событий , ваша глобальная функция window.clear затеняется устаревшими document.clear.

Это поведение объясняется в шаге 10 из получения текущего значения обработчика события :

Область действия лексической среды

  1. Если H является обработчиком события элемента , затем пусть Scope будет результатом NewObjectEnvironment ( document , global environment ).

    В противном случае, H является Window обработчиком события объекта : пусть Область действия будет глобальной средой .

  2. Если владелец формы не равен нулю, пусть Scope будет результатом NewObjectEnvironment ( владелец формы , Scope ).

  3. Если элемент не равен null, пусть Scope будет результатом NewObjectEnvironment ( element, Scope ).

Примечание: NewObjectEnvironment () определен вECMAScript edition, раздел 5 10.2.2.3 NewObjectEnvironment (O, E)

Это означает, что глобальная область действия затемнена на

  1. document
  2. Владелец формы, если есть
  3. Элемент

Следовательно, вы можете

  • Переименовать вашу функцию.

    function clear__() { document.body.style.background = 'green'; }
    <button type="button" onclick="clear__()">Click me</button>

    Этот подход не совсем надежен, поскольку некоторые браузеры могут реализовать нестандартную функцию, которая скрывает ваши переменные.Или будущая спецификация может ввести эту функцию ( пример ).

  • Вызовите вашу функцию как метод глобального объекта.

    Например,предполагая, что window не затенен, вы можете использовать window.clear.

    function clear() { document.body.style.background = 'green'; }
    <button type="button" onclick="window.clear()">Click me</button>
  • Избегайте атрибутов содержимого обработчика событий.

    Вместо этого вы можете использовать IDL-атрибуты обработчика событий или прослушиватели событий.

    function clear() { document.body.style.background = 'green'; }
    document.querySelector('button').onclick = clear;
    <button type="button">Click me</button>

    function clear() { document.body.style.background = 'green'; }
    document.querySelector('button').addEventListener('click', clear);
    <button type="button">Click me</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...