提问人:Oscar Godson 提问时间:5/29/2010 最后编辑:Peter MortensenOscar Godson 更新时间:10/23/2022 访问量:270940
JavaScript 中没有“else”的三元运算符
Ternary operators in JavaScript without an "else"
问:
我总是不得不把其他什么都没有的条件放进去。有没有办法解决它?null
例如
condition ? x = true : null;
基本上,有没有办法做到以下几点?
condition ? x = true;
现在它显示为语法错误。
仅供参考,这里有一些真实的示例代码:
!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;
答:
不,它需要三个操作数。这就是为什么它们被称为三元运算符。
但是,对于您作为示例的内容,您可以这样做:
if(condition) x = true;
尽管如果将来需要添加多个语句,使用大括号会更安全:
if(condition) { x = true; }
编辑:现在,您提到了您的问题适用于的实际代码:
if(!defaults.slideshowWidth)
{ defaults.slideshowWidth = obj.find('img').width()+'px'; }
评论
var x = condition || null;
评论
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')
或defaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
你可以写
x = condition ? true : x;
因此,当条件为 false 时,x 是未修改的。
那么这相当于
if (condition) x = true
编辑:
!defaults.slideshowWidth
? defaults.slideshowWidth = obj.find('img').width()+'px'
: null
有几个替代方案 - 我并不是说这些更好/更差 - 只是替代方案
传入 null 作为第三个参数有效,因为现有值为 null。如果重构并更改条件,则存在不再为真的危险。将现有值作为三元中的第二选择来传递,可以防止这种情况发生:
!defaults.slideshowWidth =
? defaults.slideshowWidth = obj.find('img').width()+'px'
: defaults.slideshowwidth
更安全,但可能看起来不那么好看,而且打字更多。在实践中,我可能会写
defaults.slideshowWidth = defaults.slideshowWidth
|| obj.find('img').width()+'px'
评论
首先,三元表达式不是 if/else 构造的替代品 - 它等价于返回值的 if/else 构造。也就是说,if/else 子句是代码,三元表达式是表达式,这意味着它返回一个值。
这意味着几件事:
- 仅当 左侧有一个变量时,才使用三元表达式 该变量将被赋值
=
- 仅当返回的值是两个值之一时才使用三元表达式(如果合适,则使用嵌套表达式)
- 表达式的每个部分(在 ? 之后和 : 之后)都应该返回一个没有副作用的值(表达式返回 true,因为所有表达式都返回最后一个值,但它也会更改 x,而 x 对返回的值没有任何影响)
x = true
简而言之 - 三元表达式的“正确”用法是
var resultofexpression = conditionasboolean ? truepart: falsepart;
代替您的示例,其中您使用三元表达式来设置 的值 ,您可以使用以下命令:condition ? x=true : null ;
x
condition && (x = true);
这仍然是一个表达式,因此可能无法通过验证,因此更好的方法是
void(condition && x = true);
最后一个将通过验证。
但话又说回来,如果期望值是布尔值,只需使用条件表达式本身的结果
var x = (condition); // var x = (foo == "bar");
更新
就您的样本而言,这可能更合适:
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
评论
i/else
void()
在您的例子中,我认为三元运算符是多余的。您可以使用 ||、&& 运算符将变量直接分配给表达式。
!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;
将变成:
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';
更清晰,它更像是“javascript”风格。
更常见的是,人们使用逻辑运算符来缩短语句语法:
!defaults.slideshowWidth &&
(defaults.slideshowWidth = obj.find('img').width() + 'px');
但在你的特定情况下,语法可以更简单:
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width() + 'px';
如果 的计算结果为 true,则此代码将返回该值,否则将返回 value。defaults.slideshowWidth
defaults.slideshowWidth
obj.find('img').width() + 'px'
有关详细信息,请参阅逻辑运算符的短路评估。
那干脆呢
if (condition) { code if condition = true };
要在数组或对象声明中使用三元运算符而不使用其他运算符,可以使用 ES6 扩展运算符:...()
const cond = false;
const arr = [
...(cond ? ['a'] : []),
'b',
];
// ['b']
对于对象:
const cond = false;
const obj = {
...(cond ? {a: 1} : {}),
b: 2,
};
// {b: 2}
执行此操作的简单方法是:
if (y == x) z;
我们现在还有“Nullish 合并运算符”(??它的工作方式类似于“OR”运算符,但仅返回 null 或未定义的左表达式,它不会为其他虚假值返回它。
例:
const color = undefined ?? 'black'; // color: 'black'
const color = '' ?? 'black'; // color: ''
const color = '#ABABAB' ?? 'black'; // color: '#ABABAB'
您可以考虑改用 guard 表达式(有关更多信息,请参阅 Michael Thiessen 的优秀文章)。
假设是要测试的逻辑表达式,并且是要返回的值,when 为 true。然后,您可以编写:x
z
x
y == x && z
如果为 true,则计算结果为 。如果是假的,也是.x
y
z
x
y
从技术上讲,它可以返回任何内容。 但是,我想说的是,对于单衬里,三元更容易输入,至少短 1 个字符,因此速度更快。
passTest?hasDriversLicense=true:0
if(passTest)hasDriversLicense=true
评论
为什么不写一个函数来避免 else 条件呢?
下面是一个示例:
const when = (statement, text) => (statement) ? text : null;
const math = when(1 + 2 === 3, 'Math is correct');
const obj = when(typeof "Hello Word" === 'number', "Object is a string");
console.log(math);
console.log(obj);
您还可以为任何对象实现该函数。下面是该类型的示例:string
const when = (statement, text) => (statement) ? text : null;
String.prototype.if = when;
const msg = 'Hello World!';
const givenMsg = msg.if(msg.length > 0, 'There is a message! Yayyy!');
console.log(givenMsg);
评论
condition ? x = true : null;
x = (condition ? true : null);
null
x = (condition);
if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'