在if语句中声明或不声明函数的原因



我需要确认屏幕后面发生了什么。

MDN中有一篇文章说,我们不应该在块级别声明函数,比如在if语句中声明函数。因为它在整个浏览器中都不一致,与ES2015之前(或ES6之前(的任何内容都不一致。

除非条件为true,否则不会创建if语句中的函数。

我想知道,如果条件是真的,比如说在JavaScript加载并同步设置5分钟后,会创建函数吗?它是否仍然有代码的内存来创建函数,或者它是否被转储在未使用的代码中?

我想知道即使在if语句完成之后,函数是否仍然存在。它可以访问吗?它能用多长时间?在if条件为false之前是否可以访问它?结果与ES6和ES6之前的结果不同吗?我听说if语句中没有ES6之前的范围。

例如

if (condition) { function foo() {console.log(“hello world”); } }

在读了MDN中一篇关于"非严格代码中的块级函数"下的"函数"的文章后,我感到很困惑:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

如果条件为true,比如说在JavaScript加载并同步设置5分钟后,它会创建函数吗?

一旦if运行,就会立即创建该函数。

它是否仍有代码内存以创建函数,或者它是否转储在未使用的代码中?

我想知道即使在if语句完成之后,函数是否仍然存在。它可以访问吗?它能用多长时间?

无论函数是否在if块中声明,这种行为都是相同的:如果将来没有任何东西可以引用该函数(例如,如果块结束,块内没有任何东西引用该函数(,那么它最终将被垃圾收集。该函数仍然可以";存在";在内存中保存一段时间,直到GC运行为止。

例如,应该清楚的是,以下功能应该始终存在,至少在您重新加载页面之前:

// IIFE, to get off the top level
(() => {
if (true) {
function foo() {
console.log('clicked');
}
window.addEventListener('click', foo);
}
})();

这是因为已经向addEventListener传递了对该函数的引用。

但是下面的foo函数将被GC'd(可能在页面加载后一秒钟或几秒钟,它取决于底层引擎,并且对Javascript不可见(:

// IIFE, to get off the top level
(() => {
if (true) {
function foo() {
console.log('clicked');
}
}
})();

如果在确定变量范围的块完成时,没有任何东西保存对该函数的引用,则该函数将无法在任何地方访问,并且将为GCd。

问题的其余部分看起来基本上相同:;函数在哪里可以被引用";,这在Bergi的回答中得到了最好的描述。它有点复杂,而且行为的不同取决于您是否使用严格模式、环境的ES版本和环境本身(实现并不总是符合规范(。

对于可预测、易于阅读的代码,最好不要在非函数块中使用函数声明;仅在直接位于函数块内部时使用函数声明。

(请注意,函数表达式,其中函数用作值并传递给某个对象,或立即调用或显式分配给某个变量,与函数声明不同-函数表达式很好,只是函数声明的奇怪行为有问题。另请注意,对于每个注释,"函数声明"有时是称为";函数语句"。(

最新更新