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

Ternary operators in JavaScript without an "else"

提问人:Oscar Godson 提问时间:5/29/2010 最后编辑:Peter MortensenOscar Godson 更新时间:10/23/2022 访问量:270940

问:

我总是不得不把其他什么都没有的条件放进去。有没有办法解决它?null

例如

condition ? x = true : null;

基本上,有没有办法做到以下几点?

condition ? x = true;

现在它显示为语法错误。

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

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;
JavaScript 优化 语法错误

评论

32赞 Matt S 5/29/2010
使用三元 like 可能应该写成 .顺便说一句,在 javascript 中,计算结果为 false,因此在这种情况下,您可以获得相同的结果。condition ? x = true : null;x = (condition ? true : null);nullx = (condition);
4赞 Cheeso 5/29/2010
马特,你的答案是最好的,但这不是答案,而是评论!
0赞 Oscar Godson 5/29/2010
马特,我的实际代码是: !defaults.slideshowWidth ?defaults.slideshowWidth = obj.find('img').width()+'px' : null ;一种更短、更好的写法?
3赞 kennebec 5/29/2010
defaults.slideshowWidth = defaults.slideshowWidth ||obj.find('img').width()+'px' ;
0赞 Mihail Malostanidis 9/7/2018
最好避免标识分配,因此这应该只是一个条件:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'

答:

32赞 In silico 5/29/2010 #1

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

但是,对于您作为示例的内容,您可以这样做:

if(condition) x = true;

尽管如果将来需要添加多个语句,使用大括号会更安全:

if(condition) { x = true; }

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

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

评论

1赞 Konerak 5/29/2010
你可以,但你不应该。至少不是没有大括号 - 它非常容易出错。
1赞 Cheeso 5/29/2010
这是真的吗?我明白需要卷发的主要原因是因为它们让 jslint 的生活更轻松。
1赞 Matt S 5/29/2010
@Cheeso在重构的意义上,它很容易出错。在真实情况的情况下,你回来添加更多事情要做,而没有意识到那里没有卷曲的牙套。新代码将始终执行,而不是 when true 的情况。
0赞 Oscar Godson 5/29/2010
不,我知道,我只是喜欢编写没有额外条件的条件,例如 if(){}else{},当它等于简单的 ?:;
4赞 Andy E 5/29/2010
老实说,我从来不知道开发人员比 Javascript 更害怕使用语言 :-P我不希望有人告诉我不应该使用大括号。我经常省略它们,而且从来没有比我不小心错过支架更多的麻烦。
14赞 philfreo 5/29/2010 #2
var x = condition || null;

评论

2赞 Casey Chu 5/29/2010
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')defaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
0赞 Szabolcs Páll 9/30/2015
> 如果 expr1 可以转换为 true,则返回 expr1;否则,返回 expr2。逻辑运算符 (MDN)
10赞 mdma 5/29/2010 #3

你可以写

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'

评论

0赞 Oscar Godson 5/29/2010
一些实时代码是(无论如何要摆脱其中的空值?): !defaults.slideshowWidth ?defaults.slideshowWidth = obj.find('img').width()+'px' : null ;
357赞 Sean Kinsey 5/29/2010 #4

首先,三元表达式不是 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';

评论

8赞 dewd 4/13/2015
出色的 SO,不允许编辑纠正错别字,因为它没有足够的字符。i/else
1赞 Eugene Tiurin 9/30/2015
void(condition && x = true) - 这看起来很棒,但似乎抛出“无效的赋值左侧”错误
7赞 diamondsea 3/6/2016
但是,这读起来并不直观,尤其是对于不习惯这种风格的开发人员。你可以这样简单易读地写成: if (condition) { x=true;
3赞 Koenigsberg 1/3/2018
您能否详细说明为什么只有在将条件三元运算符的结果值分配给变量时才应使用条件三元运算符?我指的是你清单中的第一点。这个意图是可以理解的,但我想知道当返回值未使用时是否有特定原因不使用三元运算符,例如性能、安全性或其他方面。
6赞 gilad905 2/2/2018
您能解释一下“可能无法通过验证”是什么意思吗?我不明白为什么要将表达式包装在 .谢谢。void()
2赞 Krasimir Kirilov 9/30/2015 #5

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

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

将变成:

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

更清晰,它更像是“javascript”风格。

18赞 Eugene Tiurin 10/1/2015 #6

更常见的是,人们使用逻辑运算符来缩短语句语法:

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

但在你的特定情况下,语法可以更简单:

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

如果 的计算结果为 true,则此代码将返回该值,否则将返回 value。defaults.slideshowWidthdefaults.slideshowWidthobj.find('img').width() + 'px'

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

3赞 Yandiro 1/12/2019 #7

那干脆呢

    if (condition) { code if condition = true };
3赞 fogx 3/29/2020 #8

要在数组或对象声明中使用三元运算符而不使用其他运算符,可以使用 ES6 扩展运算符:...()

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

对于对象:

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

原始来源

0赞 Adam 2/8/2022 #9

执行此操作的简单方法是:

if (y == x) z;
12赞 Clom 4/4/2022 #10

我们现在还有“Nullish 合并运算符”(??它的工作方式类似于“OR”运算符,但仅返回 null 或未定义的左表达式,它不会为其他虚假值返回它。

例:

const color = undefined ?? 'black';   // color: 'black'
const color = '' ?? 'black';   // color: ''
const color = '#ABABAB' ?? 'black';   // color: '#ABABAB'
3赞 Adam 4/10/2022 #11

您可以考虑改用 guard 表达式(有关更多信息,请参阅 Michael Thiessen 的优秀文章)。

假设是要测试的逻辑表达式,并且是要返回的值,when 为 true。然后,您可以编写:xzx

y == x && z

如果为 true,则计算结果为 。如果是假的,也是.xyzxy

-1赞 electroshardz 7/2/2022 #12

从技术上讲,它可以返回任何内容。 但是,我想说的是,对于单衬里,三元更容易输入,至少短 1 个字符,因此速度更快。

passTest?hasDriversLicense=true:0
if(passTest)hasDriversLicense=true

评论

0赞 Bergi 7/2/2022
"所以因此更快“——那不随之而来
0赞 Besworks 7/7/2022
这并不能提供问题的答案。一旦你有足够的声誉,你就可以对任何帖子发表评论;相反,提供不需要提问者澄清的答案。- 从评论
0赞 Reza Saadati 10/22/2022 #13

为什么不写一个函数来避免 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);