Why will the following snippet throw an error?
"use strict";
(function a() {
console.log(typeof a); // function
console.log(a = 0); // error
})();
Why doesn't this snippet throw an error?
"use strict";
(function() {
function a() {
console.log(a = 0); // 0
}
return a;
})()();
Why does immediately returning the function throw an error?
"use strict";
(function() {
return function a() {
console.log(a = 0); // error
};
})()();
Are function expressions the only case where this happens? Why can't they be reassigned?
Because that's how named FunctionExpressions behave, which is different than how FunctionDeclarations do
The rules to create a named FunctionExpression are:
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
- Let scope be the running execution context's LexicalEnvironment.
- Let funcEnv be NewDeclarativeEnvironment(scope).
- Let envRec be funcEnv's EnvironmentRecord.
- Let name be StringValue of BindingIdentifier.
- Perform envRec.CreateImmutableBinding(name, false).
- Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, funcEnv).
- Perform MakeConstructor(closure).
- Perform SetFunctionName(closure, name).
- Set closure.[[SourceText]] to the source text matched by FunctionExpression.
- Perform envRec.InitializeBinding(name, closure).
- Return closure.
The important point is the .5 which does make the name of the function an immutable binding.
In the first case, you try to reassign this Immutable Binding. It throws
In the second case however, your named function is not a FunctionExpression, but a FunctionDeclaration, which has different behavior.
In the last case, it's a FunctionExpression and to this regards does the same as the first one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With