JavaScript 显式块

4

最近我学到了关于显式块的内容。

{
   let foo = 'Hello';
   someFunction(foo);
}

我仍然不太确定它的作用以及我们(开发者)如何从中受益。

  • 您以前使用过吗?
  • 您有使用案例吗?

感谢分享你的经验!

1个回答

8

自从 ES2015 开始,let(以及 constclass,在严格模式下还有函数声明)具有块级作用域,因此您可以使用独立的块来存储私有信息,并且通常可以更细粒度地控制变量的作用域,在我们以前使用 IIFE 的地方。

也就是说,这里有一些 ES5 及更早版本的代码,其中包含一个私有变量 x

(function() {
    var x = Math.random();
    console.log(x);
})();
// `x` doesn't exist here

x 仅被封装在 IIFE 中。

现在,使用 ES2015,我们可以不创建和调用函数来实现相同的效果:

{
    let x = Math.random();
    console.log(x);
}
// `x` doesn't exist here

同样地,由于独立块可以控制变量作用域,因此我们可以更明确地控制闭包的内容。例如,考虑以下代码:
function doSomething() {
    let retainedInformation;
    {
        let something = /*...get some setup information...*/;
        let anotherThing = /*...more setup information...*/;
        let aThirdThing = /*...even more setup information...*/;
        retainedInformation = /*...something figured out using the above...*/;
    }
    return function() {
        // ...use `retainedInformation`...
    };
}

自从 `something`、`anotherThing` 和 `aThirdThing` 都超出了由 `doSomething` 返回的函数的范围,它们不会被保留,只有 `retainedInformation` 会被保留。
但是现代 JavaScript 引擎已经进行闭包优化了,所有这些设置最好放在一个你从 `doSomething` 调用的函数中,这是一般原则。
话虽如此,我们仍然可能会看到很多 IIFE,因为它们可以返回一个值。例如,如果我想要一个使用私有变量的函数,我可能会这样做:
const foo = function() {
    let privateInfo = 42;
    const foo = () => {
        console.log(privateInfo++);
    };
    return foo;
}();
foo(); // 42
foo(); // 43

相比于
let foo;
{
    let privateInfo = 42;
    foo = () => {
        console.log(privateInfo++);
    };
}
foo(); // 42
foo(); // 43

虽然两种方法都可以使用。


谢谢您的时间!我已经了解了一些关于垃圾回收的知识,并让引擎知道它可以在运行后被丢弃...保持私密性并不是显式块的唯一用途,对吧? - TheBilTheory
1
@TheBilTheory:独立块允许您更精细地控制变量的范围。我看到它主要用于隐私,但当然,变量越早超出范围,它就可以更快地被垃圾回收。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接