JavaScript中,“if”或“switch”哪个更好?

3
我正在构建一个函数,该函数在运行代码块之前验证用户的输入是否与应用程序的上下文相关。我想知道一个“if...else”语句或switch语句哪个更可靠/更好的解决方案?我倾向于使用if...else,因为我只有两个结果--用户的输入要么有效,要么告诉用户程序将接受什么,但在我深入研究之前,我希望从更有经验的人那里获得建议。
编辑:为了明确起见,当i和o都是“a”或“b”,或者都是“c”或“d”,或者都是“e”或“f”时, 我只希望我的代码执行。
    console.log("i="+i+" o="+o);
    if      
    (((i == ("a" || "b")) && (o == ("a" || "b")))
    ||  ((i == ("c" || "d")) && (o == ("c" || "d")))
    ||  ((i == ("e" || "f")) && (o == ("e" || "f"))))
    {
        //my block here
    }       
    else
    {
        //tell the user their input doesn't make sense
    }

此外,在这种情况下,我是否正确处理了布尔运算符?

2
不行,因为 ("c" || "d") 只会被计算成 "c"。所有的检查都是这种情况。你需要这样:((i == "a" || i == "b") && (o == "a" || o == "b")) - Purag
这样做比使用switch更易读 - Bala
避免提出主要基于个人观点的问题,或者那些可能会引发讨论而非答案的问题。 - VMcreator
4个回答

4

不要使用过多的or...and块,这会使其难以阅读。你可以尝试以下简单的解决方法。

在这个解决方案中,我们首先创建一个允许值的映射表,对于每个值,确定第二个变量的允许组合,然后检查变量a的值是否存在于映射表中。如果是,则检查变量i的值是否符合允许的组合。

function test(a, i) {
  var map = {
    a: ['a', 'b'],
    b: ['a', 'b'],
    c: ['c', 'd'],
    d: ['c', 'd'],
    e: ['e', 'f'],
    f: ['e', 'f']
  };

  if (map[a] && map[a].indexOf(i) > -1) {
    console.log('found', a, i, result === true)
  } else {
    console.log('not found', a, i, result === false)
  }
}


这是一个有趣的解决方案。尝试解释它是如何工作的,如何使用,并在代码中添加一些注释。 - Ori Drori
虽然我已经更改了我的代码,现在它正在运行,但你能解释一下你的意思吗?你是将预期值映射到一个二维数组中,然后检查它们是否存在,还是我完全迷失了? - Chris

4
首先,你的if语句是错误的,因为JavaScript布尔表达式会被强制转换为布尔值。
意思是:
'a'  ||  'b'

这段代码总是会返回'a',因为'a'被认为是true的,并且JS引擎不需要检查||语句的第二个操作数。

所以你的if语句应该像这样:

if(((i == "a" || i == "b") && (o == "a" || o == "b")) ||
   ((i == "c" || i == "d") && (o == "c" || o == "d")) ||
   ((i == "e" || i == "f") && (o == "e" || o == "f"))

3
首先,你的Javascript不起作用是因为非空字符串计算结果为true,所以("c" || "d")只会计算为"c"。这意味着你当前只检查io是否具有相同的值。
实际上,这已经涵盖了你需要的一半情况(如果io相等,你肯定会继续进行,无论它们是"a""b"等)。
你想要的逻辑是这样的:
if( ((i == "a" || i == "b") && (o == "a" || o == "b")) ||
    ((i == "c" || i == "d") && (o == "c" || o == "d")) ||
    ((i == "e" || i == "f") && (o == "e" || o == "f"))
){
    // valid
} else {
    // invalid
}

我更喜欢那种 if 语句,而不是你最终可能会得到的复杂的 switch

你还可以这样处理。你意识到 io 只能相差一个字母,因此可以编写以下逻辑:

if( Math.abs(i.charCodeAt(0) - o.charCodeAt(0)) <= 1 ){
    // valid
} else {
    // invalid
}

这句话的意思是只要io是同一个字母或者它们的ASCII值相差不超过1,就是有效的。这里有一个演示
check("a", "a")
// true
check("a", "b")
// true
check("a", "c")
// false
check("e", "f")
// true
check("a", "a")
// true
check("b", "a")
// true

1

你也可以这样做:

var i='a', o='b', 
    allowed = [['a','b'], ['c', 'd'], ['e', 'f']];
function test(one, two) { 
    return allowed.some(function(elem) {
        return (elem.indexOf(one)>=0 && elem.indexOf(two)>=0);
    });
}
console.log(test(i, o));

拥有一个包含所有允许值对的数组,然后使用 Array.prototype.some() 来测试你的 io 是否在允许的值范围内。.some() 会为数组中每个元素执行一次回调函数,直到找到一个使回调函数返回 true 的元素。如果找到这样的元素,则立即返回 true。
下面是代码片段:

// Only for this snippet
console.log = function(txt) {
    var result = document.getElementById("result");
    result.innerText += txt  + ", ";
}

// allowed values
var i, o, allowed = [['a','b'], ['c', 'd'], ['e', 'f']];

// function to test
function test(one, two) { 
    return allowed.some(function(elem) {
     return (elem.indexOf(one)>=0 && elem.indexOf(two)>=0);
 });
}

// all tests
i = 'a'; o = 'b';
console.log(test(i, o));
i = 'c'; o = 'd';
console.log(test(i, o));
i = 'e'; o = 'f';
console.log(test(i, o));
i = 'a'; o = 'c';
console.log(test(i, o));
i = 'd'; o = 'e';
console.log(test(i, o));
i = 'x'; o = 'y';
console.log(test(i, o));
<p id="result"></p>

还有一个可供使用的小工具:http://jsfiddle.net/abhitalks/sfuxv4ov/


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