为什么命名的 IIFE 会在其外部导致 ReferenceError?
Why does a named IIFE result in a ReferenceError outiside of it?
为什么我得到 “ReferenceError
: Person
is not defined” 下面的代码?
(function Person() {
console.log('Hi');
}());
console.log(Person);
由于函数Person
是运行,它是第一个创建的。但是,我无法解释为什么它没有被识别。我唯一的想法是 IIFE 忽略了他们给出的名字。
命名函数表达式只在它们自己的作用域.
内创建一个与其名称相匹配的变量
(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();
你得到错误是因为函数 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 中,该函数 确实 有一个名称,该名称取自变量。
语言设计者不一定需要 "why" 来做出不将名称放入范围之类的决定,但当您考虑这样做时,这样做是有道理的:
// ES5 and earlier
var x = {
foo: function foo() { /* ... */ },
bar: function bar() { /* ... */ },
baz: function baz() { /* ... */ }
};
上述将 x
添加到范围可能是有道理的,但不包括 foo
、bar
和 baz
。
为什么我得到 “ReferenceError
: Person
is not defined” 下面的代码?
(function Person() {
console.log('Hi');
}());
console.log(Person);
由于函数Person
是运行,它是第一个创建的。但是,我无法解释为什么它没有被识别。我唯一的想法是 IIFE 忽略了他们给出的名字。
命名函数表达式只在它们自己的作用域.
内创建一个与其名称相匹配的变量(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();
你得到错误是因为函数 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 中,该函数 确实 有一个名称,该名称取自变量。
语言设计者不一定需要 "why" 来做出不将名称放入范围之类的决定,但当您考虑这样做时,这样做是有道理的:
// ES5 and earlier
var x = {
foo: function foo() { /* ... */ },
bar: function bar() { /* ... */ },
baz: function baz() { /* ... */ }
};
上述将 x
添加到范围可能是有道理的,但不包括 foo
、bar
和 baz
。