提问人:Ooie 提问时间:2/29/2020 最后编辑:Ooie 更新时间:3/1/2020 访问量:1050
在 if 语句中声明函数或不声明函数的原因
Reasons to or not to declare functions in an if-statement
问:
我需要一些关于屏幕后面发生的事情的确认。
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
答:
如果条件为真,假设 JavaScript 加载并同步设置后 5 分钟后,它会创建函数吗?
该函数将在运行后立即创建。if
它是否仍然具有代码的内存以创建函数,或者它是否被转储到未使用的代码中?
我想知道即使在 if 语句完成后,该函数是否仍然存在。它是可访问的吗?它可以访问多长时间?
无论函数是否在块中声明,此行为都是相同的:如果将来没有任何东西可以引用该函数(例如,如果块结束并且块内没有任何内容引用该函数),它最终将被垃圾回收。在 GC 运行之前,该函数可能仍“存在”在内存中一段时间。if
例如,应该清楚的是,以下函数应始终继续存在,至少在重新加载页面之前是这样:
// IIFE, to get off the top level
(() => {
if (true) {
function foo() {
console.log('clicked');
}
window.addEventListener('click', foo);
}
})();
这是因为已传递了对函数的引用。addEventListener
但是以下函数将获得 GC'd(可能在页面加载后一秒钟或几秒钟 - 它取决于底层引擎,并且对 Javascript 不可见):foo
// IIFE, to get off the top level
(() => {
if (true) {
function foo() {
console.log('clicked');
}
}
})();
如果在作用域变量的块完成之前没有保存对函数的引用,则该函数将无法在任何地方访问,并且将被 GCd。
问题的其余部分看起来与“在哪里可以引用函数”基本相同,这在 Bergi 的回答中得到了最好的描述。这有点复杂,并且行为会有所不同,具体取决于您使用的是严格模式、环境的 ES 版本还是环境本身(实现并不总是符合规范)。
对于可预测的、易于阅读的代码,最好永远不要在非功能块中使用函数声明;仅当直接在功能块内部使用函数声明时。
(请注意,函数表达式,其中函数被用作值并传递给某物或立即调用或显式分配给变量,与函数声明不同 - 函数表达式很好,只是函数声明的奇怪行为有问题。另请注意,根据注释,“函数声明”有时称为“函数语句”。
评论
function fnName() { ...
评论