Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the named IIFE logged instead of the variable with the same name?

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)
})()
like image 464
Marcus Lee Avatar asked Jul 04 '19 07:07

Marcus Lee


People also ask

Can IIFE be named?

Similarly to other function IIFEs can also be named or anonymous, but even if an IIFE does have a name it is impossible to refer/invoke it. IIFEs can also have parameters.

Why do we use IIFE?

An Immediate-Invoked Function Expression (IIFE) is a function that is executed instantly after it's defined. This pattern has been used to alias global variables, make variables and functions private and to ensure asynchronous code in loops are executed correctly.

What does IIFE mean in JavaScript?

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

Which one is the correct code for IIFE?

(function () { //write your js code here }); Now, use () operator to call this anonymous function immediately after completion of its definition. (function () { //write your js code here })(); So, the above is called IIFE.


1 Answers

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:

  1. If the binding for N in envRec is a mutable binding, change its bound value to V.
  2. 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.

like image 77
CertainPerformance Avatar answered Oct 12 '22 12:10

CertainPerformance