"if" 还是 "switch" 更可取 Javascript
Is "if" or "switch" preferable Javascript
我正在构建一个函数,用于在运行代码块之前验证用户的输入在应用程序的上下文中是否有意义。我想知道像这样的 "if...else" 语句或 switch 语句是否会更有效 reliably/otherwise 是更好的解决方案?我倾向于 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
}
此外,在这种情况下我是否正确处理了我的布尔运算符?
首先,您的 if
语句是错误的,因为 JavaScript 布尔表达式被强制转换为布尔值。
含义:
'a' || 'b'
总是 return '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"))
您可以尝试如下所示的简单解决方案,而不是使用太多可能使其不可读的 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)
}
}
首先,您的 Javascript 不起作用,因为非空字符串的计算结果为 true
,因此 ("c" || "d")
仅计算为 "c"。这意味着您当前正在检查的是 i
和 o
是相同的值。
确实,这实际上涵盖了你需要的一半情况(如果i
和o
相等,你肯定继续,不管他们是否是"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
。
你也可以这样处理。你意识到 i
和 o
最多只能相差一个字母,所以你可以写出这样的逻辑:
if( Math.abs(i.charCodeAt(0) - o.charCodeAt(0)) <= 1 ){
// valid
} else {
// invalid
}
这就是说只要i
和o
是相同的字母或者相差不超过一个(用它们的ASCII值来比较),就是有效的。 Here 是一个演示。
check("a", "a")
// true
check("a", "b")
// true
check("a", "c")
// false
check("e", "f")
// true
check("a", "a")
// true
check("b", "a")
// true
您也可以这样做:
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() 测试您的 i
和 o
是否在允许值范围内。 .some()
将为数组中存在的每个元素执行一次回调函数,直到它找到一个回调函数 returns 为真值。如果找到这样的元素,它立即 returns 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>
和 fiddle 一起玩:http://jsfiddle.net/abhitalks/sfuxv4ov/
我正在构建一个函数,用于在运行代码块之前验证用户的输入在应用程序的上下文中是否有意义。我想知道像这样的 "if...else" 语句或 switch 语句是否会更有效 reliably/otherwise 是更好的解决方案?我倾向于 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
}
此外,在这种情况下我是否正确处理了我的布尔运算符?
首先,您的 if
语句是错误的,因为 JavaScript 布尔表达式被强制转换为布尔值。
含义:
'a' || 'b'
总是 return '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"))
您可以尝试如下所示的简单解决方案,而不是使用太多可能使其不可读的 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)
}
}
首先,您的 Javascript 不起作用,因为非空字符串的计算结果为 true
,因此 ("c" || "d")
仅计算为 "c"。这意味着您当前正在检查的是 i
和 o
是相同的值。
确实,这实际上涵盖了你需要的一半情况(如果i
和o
相等,你肯定继续,不管他们是否是"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
。
你也可以这样处理。你意识到 i
和 o
最多只能相差一个字母,所以你可以写出这样的逻辑:
if( Math.abs(i.charCodeAt(0) - o.charCodeAt(0)) <= 1 ){
// valid
} else {
// invalid
}
这就是说只要i
和o
是相同的字母或者相差不超过一个(用它们的ASCII值来比较),就是有效的。 Here 是一个演示。
check("a", "a")
// true
check("a", "b")
// true
check("a", "c")
// false
check("e", "f")
// true
check("a", "a")
// true
check("b", "a")
// true
您也可以这样做:
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() 测试您的 i
和 o
是否在允许值范围内。 .some()
将为数组中存在的每个元素执行一次回调函数,直到它找到一个回调函数 returns 为真值。如果找到这样的元素,它立即 returns 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>
和 fiddle 一起玩:http://jsfiddle.net/abhitalks/sfuxv4ov/