Reputation: 5930
Why did I get “ReferenceError
: Person
is not defined” for the following code?
(function Person() {
console.log('Hi');
}());
console.log(Person);
Since function Person
is run, it is first created. However, I cannot explain why it is not then recognized. My only thought is that IIFE ignores the name they are given.
Upvotes: 1
Views: 314
Reputation: 1074495
You get the error because the name of a function created by a function expression is not added to the scope the expression is in. (It is in-scope within the function body, so the name isn't just ignored.) A function declaration creates the name in the scope where it appears, but not a named function expression. That's just how JavaScript is defined.
If it's important that you stick to using an expression rather than a function declaration (for instance, because expressions are done in the step-by-step processing of the code, whereas declarations are done earlier), you can do it with a variable:
var Person = function Person() {
console.log('Hi');
};
Person();
console.log(Person);
And that gets more concise with ES6, because in ES6 you can name a function without using a named function expression:
var Person = function() {
console.log('Hi');
};
Person();
console.log(Person);
In ES5, that function wouldn't have a name (except many JavaScript engines gave it one anyway). In ES6, that function does have a name, which is taken from the variable.
Language designers don't necessarily need a "why" for decisions like not putting the name in scope, but it makes sense when you think of doing things like this:
// ES5 and earlier
var x = {
foo: function foo() { /* ... */ },
bar: function bar() { /* ... */ },
baz: function baz() { /* ... */ }
};
It probably makes sense that the above adds x
to the scope, but not foo
, bar
, and baz
.
Upvotes: 2
Reputation: 943605
Named function expressions only create a variable matching their name within their own scope.
(function Person() {
// Person is in scope here
console.log(Person);
}());
// Person is out of scope here
console.log(Person);
You need a function declaration to create a variable in the current scope. Function declarations can not be IIFEs.
If you need to create a function which you can call multiple times and call it immediately, then you need to do it in two steps:
function Person() {
console.log('Hi');
}
Person();
Upvotes: 7