【问题标题】:javascript variable scope in the IF statementIF 语句中的 javascript 变量范围
【发布时间】:2011-08-06 05:01:56
【问题描述】:

在“if”语句中声明和分配的变量是否仅在该“if”块或整个函数中可见?

我在下面的代码中做对了吗? (似乎可行,但多次声明“var 结构”似乎很尴尬)任何更清洁的解决方案?

    function actionPane(state) {
    if(state === "ed") {
        var structure = {
            "element" : "div",
            "attr" : {
                "class" : "actionPane"
            },
            "contains" : [{
                "element" : "a",
                "attr" : {
                    "title" : "edit",
                    "href" : "#",
                    "class" : "edit"
                },
                "contains" : ""
            }, {
                "element" : "a",
                "attr" : {
                    "title" : "delete",
                    "href" : "#",
                    "class" : "delete"
                },
                "contains" : ""
            }]
        }
    } else {
        var structure = {
            "element" : "div",
            "attr" : {
                "class" : "actionPane"
            },
            "contains" : [{
                "element" : "a",
                "attr" : {
                    "title" : "save",
                    "href" : "#",
                    "class" : "save"
                },
                "contains" : ""
            }, {
                "element" : "a",
                "attr" : {
                    "title" : "cancel",
                    "href" : "#",
                    "class" : "cancel"
                },
                "contains" : ""
            }]
        }
    }
    return structure;
}

【问题讨论】:

  • 请注意,您也可以这样做:if (state === "ed") { return { ... } } else { return { ... } } 而不是使用变量。

标签: javascript variables if-statement scope


【解决方案1】:

1)Variables are visible for the whole function scope。因此,您应该只声​​明一次。

2) 您不应在示例中两次声明该变量。我建议在函数顶部声明变量,然后再设置值:

function actionPane(state) {
    var structure;
    if(state === "ed") {
        structure = {    
            ...

对于 JavaScript 的出色反馈,我强烈建议使用 Douglas Crockford 的 JSLint。它将扫描您的代码以查找常见错误,并找到清理建议。

我还推荐阅读小书JavaScript: The Good Parts。它包含许多编写可维护的 JS 代码的技巧。

【讨论】:

  • @WebWanderer - 仅适用于 ES6,这很棒,但需要在客户端使用编译器。 ES5 及更早版本不支持全局或函数级范围以外的任何内容。
  • 我认为现在每个人都使用 JSHint 而不是 JSLint。
  • @KevinWheeler 这是一个相当老的答案,但任何使用 ES6 或更新版本的人都最好迁移到 ESLint
【解决方案2】:

注意:此答案来自 2011 年。不可能使用 letconst 声明变量并将其范围保持在条件 if 块内。


JavaScript 没有“块作用域”,它只有函数作用域 - 因此在 if 语句(或任何条件块)内声明的变量被“提升”到外部作用域。

if(true) {
    var foo = "bar";
}
alert(foo); // "bar"

这实际上描绘了一幅更清晰的画面(并且根据经验在采访中出现:)

var foo = "test";
if(true) {
    alert(foo); // Interviewer: "What does this alert?" Answer: "test"
    var foo = "bar";
}
alert(foo); // "bar" Interviewer: Why is that? Answer: Because JavaScript does not have block scope

函数范围,在 JavaScript 中,通常是指闭包。

var bar = "heheheh";
var blah = (function() {
    var foo = "hello";
    alert(bar); // "heheheh"
    alert(foo); // "hello" (obviously)
});

blah(); // "heheheh", "hello"
alert(foo); // undefined, no alert

函数的内部作用域可以访问它所在的环境,但反过来不行。

要回答您的第二个问题,可以通过首先构造一个满足所有条件的“最小”对象,然后根据已经/已经满足的特定条件对其进行扩充或修改来实现优化。

【讨论】:

  • Javascript 确实有块作用域。您可以使用 let myVar = "Look it up first!" Check out the let keywordif statement 中声明变量
  • @WebWanderer let 在 2015 年 12 月这里几乎不受支持,这个答案是在 2011 年 8 月发布的。
  • @trex005 是的,我明白了。从技术上讲,它尚不支持,但将与 ECMA 6 一起使用。我的评论不是针对 OP,他们已经四年多没有找到答案,而是针对其他通过这篇文章想知道如何做到这一点的人现在。把我的评论当作一厢情愿。
【解决方案3】:

ECMAScript 2015 (ES6) 包含两个新关键字,它们最终允许 JavaScript 完成正确的块作用域,而无需使用变通的口语语法:

  1. let
  2. const

【讨论】:

    【解决方案4】:

    是在“if”语句中声明和分配的变量,仅可见 在那个“if”块内还是在整个函数内?

    在 Javascript 中,所有变量都是

    • 全球范围
    • 局部作用域(整个函数) - Javascript 没有“块作用域”,其中变量仅适用于局部作用域(函数)的较小块

    我在下面的代码中做对了吗? (似乎工作,但 多次声明“var结构”似乎很尴尬)任何清洁剂 解决方案?

    是的。更简洁的解决方案可能是构建structure 的基类,并在每种情况下修改不同之处。

    【讨论】:

    • Javascript 没有类。
    • @Tomalak: Javascript 确实,但是,有对象,可以与类相媲美。
    • Javascript 有对象。但它的 OOP 模型是基于原型的,不是基于类的。
    • @WebWanderer:但是 let 仅在 IE11+ 中可用 - 所以在使用它之前确保你知道你在做什么。 caniuse.com/let - 哦,发布此答案时“让”不存在,所以请把“GRR”留给自己!
    【解决方案5】:

    在 if 语句中声明的变量将在外部可用,只要它们位于同一个函数中。

    在您的情况下,最好的方法是声明结构,然后修改对象的不同部分:

    var structure = {
        "element" : "div",
        "attr" : {
            "class" : "actionPane"
        },
        "contains" : [{
            "element" : "a",
            "attr" : {
                "title" : "edit",
                "href" : "#",
                "class" : "edit"
            },
            "contains" : ""
        }, {
            "element" : "a",
            "attr" : {
                "title" : "delete",
                "href" : "#",
                "class" : "delete"
            },
            "contains" : ""
        }]
    }
    
    if(state != "ed") {
        // modify appropriate attrs of structure (e.g. set title and class to cancel)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2013-08-14
      相关资源
      最近更新 更多