I saw the code below that someone posted. I’m confused about what it logs. It logs the function a
, not 200
. Why?
var a = 1;
(function a() {
a = 200;
console.log(a)
})()
I saw the code below that someone posted. I’m confused about what it logs. It logs the function a
, not 200
. Why?
var a = 1;
(function a() {
a = 200;
console.log(a)
})()
Because the function being immediately invoked is named, and that name cannot be reassigned to refer to something else directly inside the IIFE.
Any named function expressions will exhibit this behavior as well. A function expression whose function is named a
will mean that a
directly inside the function will always refer to the function itself, even if you try to reassign it.
You can make the error explicit if you use strict mode:
'use strict';
var a = 1;
(function a() {
a = 200;
console.log(a)
})()
Uncaught TypeError: Assignment to constant variable.
Having a named function expression is a bit like having
(function a() {
const a = <this function>;
// ...
})()
except trying to reassign it will only throw in strict mode.
Specifically, I believe the ECMAScript 5 specification for this behavior is in SetMutableBinding:
- If the binding for N in envRec is a mutable binding, change its bound value to V.
- Else this must be an attempt to change the value of an immutable binding so if S (strict mode being used) if true throw a TypeError exception.
But directly inside a function, the function name binding is not mutable - see Function Definition:
The production
FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }
is evaluated as follows:
Call the CreateImmutableBinding concrete method of envRec, passing the String value of
Identifier
as the argument.
setTimeout((function a() { a = 200; console.log(a) }), 1000)
would act the same. –
Whitehall © 2022 - 2024 — McMap. All rights reserved.