为什么我得到: ReferenceError:未定义人 以获取以下代码?
(function Person() {
console.log('Hi');
}());
console.log(Person);
由于运行了Person,因此首先创建它。但是,我无法解释为什么它不可识别。我唯一想到的是,IIEF忽略了他们给出的名字......
答案 0 :(得分:5)
命名函数表达式仅在其自己的范围内创建与其名称匹配的变量。
(function Person() {
// Person is in scope here
console.log(Person);
}());
// Person is out of scope here
console.log(Person);
您需要一个函数声明来在当前作用域中创建变量。函数声明不能是IIFE。
如果您需要创建一个可以多次调用和立即调用它的函数,那么您需要分两步完成:
function Person() {
console.log('Hi');
}
Person();
答案 1 :(得分:2)
您收到错误,因为函数 expression 创建的函数的名称未添加到表达式所在的作用域中。( 范围内的函数体,因此名称不会被忽略。)函数声明在其出现的范围内创建名称,但不是命名函数表达式。这就是JavaScript的定义方式。
如果您坚持使用表达式而不是函数声明是非常重要的(例如,因为表达式是在代码的逐步处理中完成的,而声明是在之前完成的),所以可以使用变量:
var Person = function Person() {
console.log('Hi');
};
Person();
console.log(Person);
使用ES6会更加简洁,因为在ES6中,您可以在不使用命名函数表达式的情况下命名函数:
var Person = function() {
console.log('Hi');
};
Person();
console.log(Person);
在ES5中,该函数没有名称(除了许多JavaScript引擎都给它一个)。在ES6中,该函数 具有一个名称,该名称取自变量。
语言设计师不一定需要"为什么"对于不将名称放在范围内的决定,但是当你想到这样的事情时它是有意义的:
// ES5 and earlier
var x = {
foo: function foo() { /* ... */ },
bar: function bar() { /* ... */ },
baz: function baz() { /* ... */ }
};
上述内容可能有意义,但x
,foo
和bar
会增加baz
。