How Dangerous Is It in JavaScript, Really, to Assume Undefined Is Not Overwritten

How dangerous is it in JavaScript, really, to assume undefined is not overwritten?

No, I never have. This is mostly because I develop on modern browsers, which are mostly ECMAScript 5 compliant. The ES5 standard dictates that undefined is now readonly. If you use strict mode (you should), an error will be thrown if you accidentally try to modify it.

undefined = 5;
alert(undefined); // still undefined
'use strict';
undefined = 5; // throws TypeError

What you should not do is create your own scoped, mutable undefined:

(function (undefined) {
// don't do this, because now `undefined` can be changed
undefined = 5;
})();

Constant is fine. Still unnecessary, but fine.

(function () {
const undefined = void 0;
})();

Possible ways to detect where 'undefined' is being overwritten?

You should never be using undefined as if it were a value anyway. The correct way to test for undefined-ness is typeof somevar == "undefined"

Is there anything wrong with using 'var undefined' to test for undefined

Don't redefine undefined.

Other programmers expect undefined to always be undefined, not a function for function's sake.

People often use typeof operator to ensure a reference error is not thrown when used to test for variables that are undefined.

If anyone ever does this to you, you can use...

undefined = void 0;

... to revert it back.

JavaScript: undefined !== undefined?

It turns out that you can set window.undefined to whatever you want, and so get object.x !== undefined when object.x is the real undefined. In my case I inadvertently set undefined to null.

The easiest way to see this happen is:

window.undefined = null;
alert(window.xyzw === undefined); // shows false

Of course, this is not likely to happen. In my case the bug was a little more subtle, and was equivalent to the following scenario.

var n = window.someName; // someName expected to be set but is actually undefined
window[n]=null; // I thought I was clearing the old value but was actually changing window.undefined to null
alert(window.xyzw === undefined); // shows false

The dangers of overwriting JavaScript object and functions

Monkey patching builtin classes like that is a controversial topic. I personally don't like doing that for 2 reaons:

  1. Builtin classes are a global scope. This means that if two different modules try to add methods with the same name to the global classes then they will conflict, leading to subtle bugs. Even more subtly, if a future version of a browsers decides to implement a method with the same name you are also in trouble.

  2. Adding things to the prototypes of common classes can break code that uses for-in loops without a hasOwnProperty check (people new to JS often do that to objects and arrays, since for-in kind of looks like a foreach loop). If you aren't 100% sure that the code you use is using for-in loops safely then monkeypatching Object.prototype could lead to problems.

That said, there is one situation where I find monkeypatching builtins acceptable and that is adding features from new browsers on older browsers (like, for example, the forEach method for arrays). In this case you avoid conflicts with future browser versions and aren't likely to catch anyone by surprise. But even then, I would still recommend using a shim from a third party instead of coding it on your own, since there are often many tricky corner cases that are hard to get right.

How to set a javascript var as undefined

delete boo

Don't use var boo = undefined. undefined is just a variable and if someone sets undefined = "hello" then you'll be getting hello everywhere :)

EDIT:

null wasn't same as undefined. removed that bit.

Detecting an undefined object property

The usual way to check if the value of a property is the special value undefined, is:

if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}

To check if an object does not actually have such a property, and will therefore return undefined by default when you try to access it:

if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}

To check if the value associated with an identifier is the special value undefined, or if that identifier has not been declared:

if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}

Note: this last method is the only way to refer to an undeclared identifier without an early error, which is different from having a value of undefined.

In versions of JavaScript prior to ECMAScript 5, the property named "undefined" on the global object was writeable, and therefore a simple check foo === undefined might behave unexpectedly if it had accidentally been redefined. In modern JavaScript, the property is read-only.

However, in modern JavaScript, "undefined" is not a keyword, and so variables inside functions can be named "undefined" and shadow the global property.

If you are worried about this (unlikely) edge case, you can use the void operator to get at the special undefined value itself:

if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}

Is array[index] === undefined the always same as typeof array[index] === 'undefined'?

Yes there is a very obscure edgecase:

let undefined = "confuse me!";

that means that

 "confuse me!" === undefined

might be true and

typeof undefined === "undefined"

might be false, but if

 typeof arrayName[index] === "undefined" 

is true then its definetly not defined, however it might not be undefined :)

But as this is terrible, you don't really have to consider that.



Related Topics



Leave a reply



Submit