例如,这样的事情:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
有没有更好的写法?同样,我不是在寻求上述确切问题的答案,只是一个示例,说明何时可能在三元运算符表达式中重复操作数...
例如,这样的事情:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
有没有更好的写法?同样,我不是在寻求上述确切问题的答案,只是一个示例,说明何时可能在三元运算符表达式中重复操作数...
就我个人而言,我认为最好的方法仍然是古老的if
声明:
var value = someArray.indexOf(3);
if (value === -1) {
value = 0;
}
代码应该是可读的,所以简洁不意味着不惜一切代价要简洁——为此你应该重新发布到https://codegolf.stackexchange.com/——所以我建议使用名为的第二个局部变量index
来最大化阅读理解(我注意到,运行时间成本也最低):
var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;
但是如果你真的想减少这种表达,因为你对你的同事或项目合作者来说是一个残酷的虐待狂,那么你可以使用以下 4 种方法:
var
语句中的临时变量当用逗号分隔时,您可以使用var
语句的功能来定义(和分配)第二个临时变量index
:
var index = someArray.indexOf(3), value = index !== -1 ? index: 0;
另一种选择是自执行匿名函数:
// Traditional syntax:
var value = function( x ) { return x !== -1 ? x : 0 }( someArray.indexOf(3) );
// ES6 syntax:
var value = ( x => x !== -1 ? x : 0 )( someArray.indexOf(3) );
还有臭名昭著的“逗号运算符”,JavaScript 支持它,它也存在于 C 和 C++ 中。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
当您希望在需要单个表达式的位置包含多个表达式时,可以使用逗号运算符。
您可以使用它来引入副作用,在这种情况下,通过重新分配给value
:
var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );
这是有效的,因为var value
它首先被解释(因为它是一个语句),然后是最左边、最内部的value
赋值,然后是逗号运算符的右边,然后是三元运算符 - 所有合法的 JavaScript。
评论员@IllusiveBrian 指出,如果将 to 赋值value
用作带括号的子表达式,则不需要使用逗号运算符(在前面的示例中):
var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );
请注意,在逻辑表达式中使用否定词对人类来说可能更难理解 - 因此可以通过更改idx !== -1 ? x : y
为来简化上述所有示例以供阅读idx == -1 ? y : x
:
var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
对于数字
您可以使用该Math.max()
功能。
var value = Math.max( someArray.indexOf('y'), 0 );
它将保持结果的边界0
直到第一个结果大于0
如果是这种情况。如果结果来自indexOf
is-1
它将返回 0 大于-1
。
对于 booleans 和 boolean-y 值
对于 JS 没有一般规则 AFAIK 特别是因为如何评估虚假值。
但是,如果大多数时候可以帮助您的是 or 运算符 ( ||
):
// Instead of
var variable = this_one === true ? this_one : or_this_one;
// you can use
var variable = this_one || or_this_one;
你必须非常小心,因为在你的第一个例子中,indexOf
可以返回0
,如果你评估0 || -1
它会返回,-1
因为它0
是一个假值。
不是真的,只需使用另一个变量。
你的例子概括为这样的事情。
var x = predicate(f()) ? f() : default;
您正在测试一个计算值,然后将该值分配给一个变量,如果它通过某个谓词。避免重新计算计算值的方法很明显:使用变量来存储结果。
var computed = f();
var x = predicate(computed) ? computed : default;
我明白你的意思 - 似乎应该有一些看起来更干净的方法来做到这一点。但我认为这是(惯用的)最好的方式来做到这一点。如果您出于某种原因在代码中多次重复此模式,您可能会编写一个小辅助函数:
var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
利用 ||
const result = a ? a : 'fallback value';
相当于
const result = a || 'fallback value';
如果强制转换a
为Boolean
返回false
,result
将被赋值'fallback value'
,否则为 的值a
。
请注意边缘情况a === 0
,它转换为false
并且result
将(错误地)采用'fallback value'
. 使用此类技巧的风险自负。
附注。Swift 等语言有nil-coalescing运算符 ( ??
),其用途类似。例如,在 Swift 中,您会编写result = a ?? "fallback value"
非常接近 JavaScript 的const result = a || 'fallback value';