IF 语句中的 javascript 变量范围

IT技术 javascript variables if-statement scope
2021-02-19 20:03:23

在“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;
}
5个回答

1)变量对整个函数作用域都是可见的因此,您应该只声​​明一次。

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

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

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

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

@WebWanderer - 仅适用于 ES6,这很棒,但需要在客户端使用编译器。ES5 及更早版本不支持除全局或函数级作用域之外的任何其他内容。
2021-04-28 20:03:23
@KevinWheeler 这是一个相当古老的答案,但任何使用 ES6 或更新版本的人都最好迁移到ESLint
2021-04-28 20:03:23
我认为现在每个人都使用 JSHint 而不是 JSLint。
2021-05-02 20:03:23

注意:此答案来自 2011 年。不可能使用let声明变量const并将其范围保留在条件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

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

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

@trex005 是的,我明白了。从技术上讲,它还不受支持,但将与 ECMA 6 一起使用。我的评论不是针对 OP,他已经四年多没有找到答案,而是针对其他人通过这篇文章想知道如何做到这一点现在。把我的评论当作一厢情愿。
2021-04-25 20:03:23
Javascript 确实有块作用域。您可以在if statementusing 中声明变量let myVar = "Look it up first!" 检查let关键字
2021-04-28 20:03:23
@WebWanderer let 在 2015 年 12 月几乎不受支持,此答案于 2011 年 8 月发布。
2021-05-19 20:03:23

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

  1. 常量

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

在 Javascript 中,所有变量都是

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

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

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

Javascript 有对象。但它的 OOP 模型是基于原型的,而不是基于类的。
2021-04-20 20:03:23
Javascript 没有类。
2021-05-04 20:03:23
@Tomalak:但是,Javascript确实具有与类相当的对象。
2021-05-17 20:03:23
@WebWanderer:但是 let 仅在 IE11+ 中可用 - 所以在使用它之前确保你知道你在做什么。caniuse.com/let - 哦,当这个答案发布时,“let”并不存在,所以把你的“GRR”留给自己!
2021-05-18 20:03:23

在 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)
}