What does this line below do?
undefined = 'A value';
If it does not change the value of undefined then what happens behind the scenes?
What does this line below do?
undefined = 'A value';
If it does not change the value of undefined then what happens behind the scenes?
undefinedis a property of the global object, i.e. it is a variable in global scope. The initial value ofundefinedis the primitive valueundefined.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined
So, it's just a variable, nothing special about it. Now, to answer your questions:
undefined = 'A value'; attempts to assign a string 'A value' to the global variable undefinedundefined === 'A value'; // true. In newer browsers under strict mode the operation results in an error. You can test the following in a browser console (I'm using a modern browser here - Google Chrome):
undefined = true;
console.log(undefined); // undefined
// in older browsers like the older Internet Explorer it would have logged true
The value of undefined doesn't change in the above example. This is because (emphasis mine):
In modern browsers (JavaScript 1.8.5 / Firefox 4+), undefined is a non-configurable, non-writable property per the ECMAScript 5 specification.
Under strict mode:
'use strict';
undefined = true; // VM358:2 Uncaught TypeError: Cannot assign to read only property 'undefined' of object
Unlike things like true, 123 or null, undefined is not a literal. That means using the undefined identifier is not a foolproof way to obtain the undefined value. Instead, can use the void operator, e.g. void 0.
By default, undefined defined a property of the global object, that is, global variable. Before ECMAScript 5, that property was writable, so
undefined = "A value";
replaced the value of window.undefined, assuming it was not shadowed by a local variable. Then if you used "A value" === undefined, you would get true. And void 0 === undefined would produce false.
ECMAScript 5 changed this behavior, and now the property is not writable nor configurable. Therefore, assignments to undefined will be ignored in non-strict mode, and will throw an exception is strict mode. Under the hood,
undefined = "A value"; is a Simple Assignment"A value" in a reference with base the global object, referenced name "undefined", and strict flag if the assignment is made in strict mode."undefined" as the property name, "A value" as the value, and the strict flag as the throw flag."undefined", the property descriptor {[[Value]]: "A value"}, and the throw flag as arguments.However, you are still able to declare local undefined variables:
(function() {
var undefined = "A value";
alert(undefined); // "A value";
})();
I've made a little POC with and without strict mode.
The effect is that, if you're not using strict mode everything goes fine. If you're using strict mode you'll have a nice:
TypeError: Cannot assign to read only property 'undefined'
Now let's get to the POC:
"use strict"
var c;
if (c === undefined) {
console.log("nothing happened")
}
undefined = "goofy"
c = "goofy"
if (c === undefined) {
console.log("c is 'goofy' and it's equal to undefined.. gosh.. we broke js")
}
Now, as I said, with strict mode you obtain a TypeError while removing the "use strict" the script goes fine and the output is simply nothing happened.
I've found this Q/A that could be useful if you want to know more
NOTE: I've tested this code using Node.js.
in addition to Oriol answer
you can also have a block-level undefined variable
{
let emptyVar;
// console.log(emptyVar === undefined); // Cannot access 'undefined' before initialization
const undefined = "some value";
console.log(undefined);
console.log(void 0); // primitive undefined
}