Why is undefined not writable in JavaScript?
According to MDN's documentation on undefined
:
In modern browsers (JavaScript 1.8.5 / Firefox 4+), undefined is a non-configurable, non-writable property per the ECMAScript 5 specification. Even when this is not the case, avoid overriding it.
One of the property attributes of undefined is that is not writable.
But if I do:
var undefined = 'hello';
var test = undefined;
console.log(typeof test);
//string
Does that mean that I can overwrite the value of undefined
? What happens if someone does that? Should JavaScript warn about that?
Solution 1:
A removed comment by Amy gives the solution. You are creating a variable named undefined
, and it doesn't work if you do your snippets in the global scope:
var undefined = 'hello';
var test = undefined;
console.log(typeof test);
But it effectively works if you do it in a local scope where undefined doesn't refer to the global variable anymore:
(()=>{
var undefined = 'hello';
var test = undefined;
console.log(typeof test);
})()
To prevent this mistake, you can use the 'use strict';
directive:
'use strict';
var undefined = 'hello';
var test = undefined;
console.log(typeof test);
If you are writing code where you can't control where it will be executed (e.g. library, embed, etc) it is a good pattern to use a IIFE which makes it so you can guarantee that undefined will always be correct/usable. Here is an example:
(function(undefined){
// undefined will equal `undefined` because we didn't pass in an argument to the IIFE
console.log(undefined); // always `undefined`, even if undefined !== `undefined`outside of the IIFE scope
})(); // No argument supplied
All my tests were made using Firefox 72.0b10 (64 bits) on Ubuntu, and the result for the first snippet may differ on an older browser.
Solution 2:
While it is possible to use it as an identifier (variable name) in any scope other than the global scope (because undefined is not a reserved word), doing so is a very bad idea that will make your code difficult to maintain and debug.
Source https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined
undefined
is not reserved hence it is possible to assign it a new value.
When you are not using strict mode
you are essentially creating a variable called undefined
in local scope and assigning a string
value to it.
undefined
is a property of the global object. The initial value of undefined is the primitive value undefined
.
use strict
will help prevent this mistake in global scope while it can still be overwritten in local scope.
If you want to be more safe you should use void 0
instead of undefined
which always returns undefined
.
'use strict'
const test = (() => {
let undefined = "test"
console.log(typeof undefined)
console.log(typeof void 0)
})()