For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/year/pending/proposal-Declarations-in-Conditionals.md.
  • 简体中文
  • Declarations in Conditionals S1

    中文标题:条件语句中的声明

    提案概览
    提案速览

    该提案允许在 ifwhile 等条件语句中直接进行变量声明,将声明与真值性检查结合在一起。它建议支持 letconstusingawait using,同时将声明的变量限制在 if 块内,并要求在逗号分隔列表或解构等场景中在分号后提供额外的表达式。这样可以只对值求值一次,避免重复名称,并减少作用域污染。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    条件语句中的声明

    ECMAScript 提案,用于允许在条件语句(例如 if/while)中进行变量声明。

    作者:

    • Devin Rousso

    阶段:1

    候选规范文本 可用。

    概述

    在使用 C++ 编程时,一个极其有用的特性是能够声明一个变量_并_在条件内对其进行求值:

    if (auto* ptr = getPtr()) {
        /* ... */
    }
    
    if (auto* ptr = getPtr(); ptr && ptr->value) {
        /* ... */
    }

    为 JavaScript 添加此功能将非常有用,原因如下:

    • 避免必须重新输入变量名
    • 对变量的可见性进行更细粒度的“控制”
    • 允许作者编写对性能“安全”的代码,而无需了解被调用代码的具体细节(参见下面的示例)

    然而,就 JavaScript 而言,应该有一些限制:

    • 仅使用 letconstusingawait using
    • 仅用于 ifwhile
    • 仅在 if 块中暴露(即不在 else 中)
    • 逗号分隔列表、解构等需要在 ; 后提供第二个表达式,以明确正在测试的内容

    示例

    以下是一个允许在条件中进行声明可能会有用的示例:

    class Foo {
        get data() {
            let result = [];
            /* ... do some expensive work ... */
            return result;
        }
    }
    
    let foo = new Foo;
    if (foo.data) {
        for (let item of foo.data) {
            /* A */
        }
    } else {
        /* B */
    }

    可以替换为

    class Foo {
        get data() {
            let result = [];
            /* ... do some expensive work ... */
            return result;
        }
    }
    
    let foo = new Foo;
    if (let data = foo.data) {
        for (let item of data) {
            /* A */
        }
    } else {
        /* B */
    }

    这使得 foo.data 只需要被求值一次,并且在风格上更加简洁。

    人们可以创建另一个变量(例如 let data = foo.data;),但这可能会使 foo.data(通过 data)存活的时间远超所需,并且会用额外的变量“污染”作用域。

    作为另一个示例,非 module<script> 需要额外的块来限制临时绑定的作用域:

    <meta name="color-scheme" content="light dark">
    <script>
    {
        const colorScheme = localStorage.getItem("color-scheme");
        if (colorScheme) {
            document.querySelector('meta[name="color-scheme"]').content = colorScheme;
        }
    }
    </script>

    如果我们能将声明移到条件中,就不需要这样了:

    <meta name="color-scheme" content="light dark">
    <script>
    if (const colorScheme = localStorage.getItem("color-scheme")) {
        document.querySelector('meta[name="color-scheme"]').content = colorScheme;
    }
    </script>

    转译器支持

    这可以使用块和生成的标签进行转译:

    class Foo {
        get data() {
            let result = [];
            /* ... do some expensive work ... */
            return result;
        }
    }
    
    let foo = new Foo;
    __if0: {
        {
            let data = foo.data;
            if (data) {
                {
                    for (let item of data) {
                        /* A */
                    }
                }
    
                break __if0;
            }
        }
    
        {
            /* B */
        }
    }

    注意,__if0 表示由转译器选择的新鲜标签,因此它不会与源码中的任何标签冲突。