没有“ Else”的JavaScript中的三元运算符


149

我一直不得不放置null没有任何其他条件的条件。反正周围有吗?例如

condition ? x = true : null;

基本上,有什么方法可以做:

condition ? x = true;

现在它显示为语法错误

仅供参考,这是一些真实的示例代码:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;

21
三元之类的使用condition ? x = true : null;应该写成x = (condition ? true : null);。顺便说一句,在javascript中null评估为false,因此在这种情况下,您可以x = (condition);并达到相同的结果。
Matt S

1
马特,您的答案是最好的,但这不是答案,而是评论!
Cheeso 2010年

马特,我的实际代码是:!defaults.slideshowWidth?defaults.slideshowWidth = obj.find('img')。width()+'px':null; 一种更短,更好的书写方式?
奥斯卡·戈德森

2
defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img')。width()+'px';
肯纳贝克

最好避免身份分配,所以这应该只是一个条件:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

Answers:


226

首先,三元表达式不能替代if / else构造-它等同于返回值的if / else构造。也就是说,if / else子句是code,三元表达式是expression,表示它返回一个值。

这意味着几件事:

  • 仅当在变量的左侧=具有要分配返回值的变量时,才使用三元表达式
  • 仅在返回值是两个值之一时才使用三元表达式(如果合适则使用嵌套表达式)
  • 表达式的每个部分(在?和after:之后)都应返回一个无副作用的值(该表达式x = true返回true,因为所有表达式都返回最后一个值,但也要更改x,而x不会对返回值产生任何影响)

简而言之-三元表达式的“正确”用法是

var resultofexpression = conditionasboolean ? truepart: falsepart;

condition ? x=true : null ;可以使用以下代码代替使用三元表达式设置的值的示例x

 condition && (x = true);

这仍然是一个表达式,因此可能无法通过验证,因此一种更好的方法是

 void(condition && x = true);

最后一个将通过验证。

但是再说一次,如果期望值是布尔值,则只需使用条件表达式本身的结果

var x = (condition); // var x = (foo == "bar");

UPDATE 对于您的示例,这可能更合适:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

4
太棒了,i/else因为字符不够,不允许编辑来纠正错字。
2015年

1
void(condition && x = true)-这看起来不错,但似乎抛出“无效分配左侧”错误
Eugene Tiurin

1
空隙(条件&&(X =真))//保持分配从所述第一值独立
diamondsea

4
但是,阅读起来并不直观,特别是对于不习惯这种风格的开发人员。您可以像这样轻松而又可读地编写它:if(condition){x = true; }
diamondsea

2
您能否解释“可能不通过验证”是什么意思?我不明白为什么要用来包装表达式void()。谢谢。
吉拉德·玛雅妮

20

不,它需要三个操作数。这就是为什么它们被称为三元运算符。

但是,以您的示例为例,您可以执行以下操作:

if(condition) x = true;

如果将来需要添加多个语句,则使用花括号更安全:

if(condition) { x = true; }

编辑:现在,您提到了您的问题适用于的实际代码:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }

1
可以,但是不可以。Atleast并非没有大括号,这很容易出错。
Konerak 2010年

1
真的吗?我了解需要curl的主要原因是因为它们使jslint的生活更加轻松。
Cheeso 2010年

@Cheeso在重构方面很容易出错。在没有遇到大括号的情况下,您又回来了以增加在真实情况下的工作量。新代码将始终执行,而不是true的情况。
Matt S 2010年

不,我不知道,我只喜欢编写无条件的条件语句,例如if(){} else {},它等于?:;。
奥斯卡·戈德森

3
老实说,我从来没有听说过比Javascript更害怕使用语言的开发人员:-PI不希望有人告诉我我不应该使用花括号。我忽略了很多,并且没有比我意外丢失括号更大的麻烦了。
安迪E

12

人们越来越多地使用逻辑运算符来缩短语句语法:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

但是在您的特定情况下,语法甚至可以更简单

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

defaults.slideshowWidth如果将defaults.slideshowWidth评估为true,则此代码将返回obj.find('img').width()+'px'值,否则返回value。

有关详细信息,请参见逻辑运算符的短路评估



5

你可以写

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'

一些实时代码是(无论如何要摆脱其中的null?):!defaults.slideshowWidth?defaults.slideshowWidth = obj.find('img')。width()+'px':null;
奥斯卡·戈德森

2

在您的情况下,我认为三元运算符是多余的。您可以使用||,&&运算符将变量直接分配给表达式。

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

会变成 :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

更清晰,更“ javascript”风格。



1

要使用三元运算符而不在数组或对象声明内使用其他函数,则可以使用ES6传播运算符 ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

对于对象:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

原始资料

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.