3

It's been a while since ECMAScript 5 came out and is being supported quite well in most modern browsers (IE9, CH 19+, FF 4+) and with it so is the "Immutable undefined". Though I keep seeing "undefined" being passed like so:

(function ( ..., undefined ) {

})(...);

From what I can tell Crockford's JSLint tool doesn't really like it:

Expected an identifier and instead saw 'undefined' (a reserved word).

Even though it's not being passed (there's no argument on the function call) and it's really an identifier. I understand that his tool isn't a bible we should follow to the death and on the other hand JSHint doesn't seem to care about it.

Is this still considered a best practice today and how does it affect code performance/security? Considering browser support >= IE9.

Community
  • 1
  • 1
Jonny Sooter
  • 2,417
  • 1
  • 24
  • 40
  • @bfavaretto no, It is immutable everywhere most modern browsers `undefined = 1; undefined; // undefined` – Paul S. Jan 28 '13 at 17:01

2 Answers2

3

Is this still considered a best practice today and how does it affect code performance/security? Considering browser support >= IE9.

Much like undefined, Infinity is a non-writable property of the global object rather than a literal like null, so it can be used as a parameter name without raising an error. Lets consider a function like this

function example(Infinity) {
    return Infinity;
}

In example, Infinity is no longer a non-writable property and instead acts like any other parameter to a function, initialised as undefined if nothing is passed or otherwise taking the value of the argument. This means in this function you can't just assume Infinity will mean Infinity, because it doesn't, but you could assume it will mean undefined.

So let's go back to the question of undefined. It will be initialised as undefined so the meaning will stay the same, however, it has now lost it's immutability within the function and therefore any typos assinging a values to undefined will have this error carried forward. Additionally, if a parameter is passed to the function the value will be different from the start.

Therefore to conclude, it does have an effect on security, as an undefined like this is no longer as "safe" because it has lost it's immutable status and can be changed.


It may be interesting to note that undefined is not actually a reserved word. If you require an undefined for compatibility, rather than adding it as a parameter name, I would suggest using a simple var undefined; at the top of the function or in the global namespace where you will find var undefined; undefined = 1; undefined; // undefined where it is immutable.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
0

If you wanted to comply with jsLint, you could use another variable that is not a reserved word instead of undefined. The following complies with jsLint:

(function (window, document, undef) {
    'use strict';

}(window, document));

You would, however, need to remember to use your newly defined variable (in this case undef instead of undefined). The strict mode above was added to comply with jsLint. This is mostly used so that you know for certain that the variable you are testing to be undefined is actually undefined.

Note, that if you're running this example in the text area provided on the jsLint website, you may need to define window and document. I was receiving two errors until I did so.

var window = window; //global window object
var document = document; //global window object

However, I'm of the opinion that:

(function (..., undefined) {
    'use strict';

}(...));

is perfectly fine and more importantly, highly recommended.

There are cases where reserved words can be changed from their normal states. Such as setting undefined to true. Paul Irish discusses this briefly in his video: http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/

Chase
  • 29,019
  • 1
  • 49
  • 48
  • In Firefox, `(function (undefined) { 'use strict'; alert(undefined); })(1);` alerts `1`. It seems like strict mode does not disallow the function parameter from monopolizing `undefined`. – apsillers Jan 28 '13 at 17:29
  • The `strict mode` above was added to comply with jsLint. Your example above works exactly as to be expected. However, since you are the one programming and wrapping your code in the anonymous self-executing function, why would you knowingly do so? – Chase Jan 28 '13 at 17:32
  • Aha, I was just about to clarify my question. I didn't understand that your recommendation to use strict mode was validation-oriented; now I get it. – apsillers Jan 28 '13 at 17:33
  • I can see how that may have been a bit unclear. I'll add a bit more clarification. – Chase Jan 28 '13 at 17:34