Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "clear" a reserved word in Javascript?

Tags:

javascript

I just spent a long time figuring out that I shouldn't use clear() as the name of a function in 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>

Here's 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";
}

Symptoms: Clicking the 'add' and 'check' buttons gives me the result I expect, but clicking the 'clear' button does nothing.

If I rename clear() to clearxyz(), it works fine.

My questions:

  1. Is "clear" a reserved word? I don't see it on the list: https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
  2. Is there a debugging trick I should be using to figure this kind of thing out in the future? It took me a long time (I'm a noob!) to figure out that the name of the function was my problem.

Many thanks. Edit: I'm using Firefox 6.0, and I added a line break to show where Array.js starts.

like image 466
Uncle Vinny Avatar asked Aug 23 '11 18:08

Uncle Vinny


People also ask

Is there a clear function in JavaScript?

clear() function in JavaScript. The clear() function of the Set object removes all elements from the current Set object.

What is clear in JS?

The JavaScript Set clear() method is used to remove all the elements from Set object.

Is delete a reserved word in JavaScript?

1). This means you cannot use delete as a variable or function name, but you can use it as an object property name. This was not the case in the previous version of the specification, which is why most other answers are recommending you avoid using reserved words entirely.

Which of the following is not a reserved word in JavaScript?

The NaN , Infinity , and undefined are not reserved keywords in JavaScript But you must avoid using them. They are properties of the global object and have special meanings.


4 Answers

As the others said, clear is not a reserved keyword. It seems that the called function is document.clear [MDN]. Invoking

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

inside the event handler returns true.

DEMO

So it seems, document is in the scope chain of the event handler.... the question now is why.

JavaScript: The Definitive Guide says:

In an event handler as HTML attribute, the Document object is in the scope chain before the Window object (...)

As your method is global, meaning it is a property of the window object, it is not found in the scope chain, as document.clear comes earlier in the scope chain.

I haven't found any specification for this. The guide also says that one should not rely on that, so I assume this is nothing official.

If you have form elements inside a form, then even the corresponding form element will be in the scope chain (not sure whether this holds for all browsers though). This is another reason for confusion.


There are two (not exclusive) ways to avoid such situations:

  • Don't use inline event handlers. It is considered bad practice as it is mixing logic and presentation. There are other ways to attach event handlers.

  • Don't pollute the global namespace. Create one object in global scope (with a name you are sure of does not collide with any window or document properties or ids of HTML elements) and assign the functions as properties of this object. Whenever you call a function, you reference it through this object. There also other ways to namespace your code.

like image 65
Felix Kling Avatar answered Oct 04 '22 16:10

Felix Kling


No, clear is not a reserved keyword.

The problem is that, since you use an event handler content attribute, your global function window.clear is shadowed by the obsolete document.clear.

This behavior is explained in step 10 of getting the current value of the event handler:

Lexical Environment Scope

  1. If H is an element's event handler, then let Scope be the result of NewObjectEnvironment(document, the global environment).

    Otherwise, H is a Window object's event handler: let Scope be the global environment.

  2. If form owner is not null, let Scope be the result of NewObjectEnvironment(form owner, Scope).

  3. If element is not null, let Scope be the result of NewObjectEnvironment(element, Scope).

Note: NewObjectEnvironment() is defined in ECMAScript edition 5 section 10.2.2.3 NewObjectEnvironment (O, E)

That means that the global scope is shadowed by

  1. The document
  2. The form owner, if any
  3. The element

Therefore, you can

  • Rename your function.

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

    This approach is not completely reliable because some browser could implement a non-standard feature which shadows your variables. Or a future spec could introduce that feature (example).

  • Call your function as a method of the global object.

    For example, assuming window is not shadowed, you can use window.clear.

    function clear() { document.body.style.background = 'green'; }
    <button type="button" onclick="window.clear()">Click me</button>
  • Avoid event handler content attributes.

    Instead, you can use event handler IDL attributes or event listeners.

    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>
like image 45
Oriol Avatar answered Oct 04 '22 17:10

Oriol


Not according to the MDN.

Edit:

You got me curious, so I threw together this little jsfiddle.

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

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

Having a function named clear seems to work just fine.

like image 32
Jonathan Beebe Avatar answered Oct 04 '22 18:10

Jonathan Beebe


Good question. I think the problem is a scoping issue - your onClick="clear()" is not going to the clear function you defined, but I'm not sure where it's going. Changing it to window.clear() or a new function that simply calls your clear works.

<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>
like image 40
rosscj2533 Avatar answered Oct 04 '22 16:10

rosscj2533