这些JavaScript代码行是否等价?

我在JavaScript代码中find了这个string。

var c = (ab !== null) ? ab : null; 

这是if-else语句的缩写,但是如果为空,则赋值null。 是不是总是相当于

 var c = ab 

包括所有的情况 – 例外,空,未定义等?

换句话说,这些线(总是)是相等的吗?

 var c = (ab !== null) ? ab : null; 

航class吗

 var c = ab 

不,如果b是一个更新variables的getter,它们不是必须的。 尽pipe这样编码是不好的做法

 var log = 0; var a = { get b() { log++; return log; } } var c = (ab !== null) ? ab : null; // outputs 2 console.log(c); 
 var log = 0; var a = { get b() { log++; return log; } } var c = ab; // outputs 1 console.log(c); 

这些陈述在逻辑上是等同的。

这就是说,正如在另一个答案中提到的,如果ab有副作用,这些语句不会导致相同的程序状态。

如果ab修改程序中其他地方的某些内容,取决于执行这些语句中的哪一个, var c具有不同的值,这可能是显而易见的,或者更加隐藏。

重构

由于重构已经被讨论过了,我会简单地谈谈它。 正如上面希望显而易见的,直接重构在所有情况下都是不安全的 。 不过,我仍然会推荐这样或那样的重构。

我看到的两种可能的情况是:

  1. ab没有副作用,直接重构是安全的
  2. ab有隐藏的副作用。 这代表非常不清楚,混乱,只是彻头彻尾的坏代码 。 它应该被重构,以便在陈述过程中发生的所有变化对读者来说都是清楚而明显的(希望直观地如此以及由评论支持)。

正如@potatopeelings已经指出的那样,这两个可能的语句并不总是等价的,因为可以编写不明确的代码,这会得到不同的结果。

但是,如果我看到一个代码,就像

 var c = (ab !== null) ? ab : null; 

我会假设代码的意图是

 var c = ab; 

所以我会改变它,使代码更漂亮。 如果我会感到负面的惊讶,也就是说,由于这个改变,代码没有通过testing阶段,那么我会尝试用git blamefindab的作者。

所以,我的回答是,这两个陈述是不相同的,但应该在写得很好的代码中相当。

那么,甚至不是

 var c = (a !== null) ? a : null; 

保证相当于

 var c = a; 

当由全局对象上的getter或ES6代理处理程序parsinga时。

因此,举例来说,这赋值为0的值:

 Object.defineProperty(self, 'a', { get: function() { return c ^= 1; } }); var c = (a !== null) ? a : null; console.log(c); 

你是对的, var c = abvar c = (ab !== null) ? ab : null;完全一样var c = (ab !== null) ? ab : null; var c = (ab !== null) ? ab : null;

我的猜测是三元运算符中的null是指任何东西,除了null值,如果你愿意,它是一个默认值。

奇怪的语法混乱的原因是因为ab可能是一个空string或未定义,显然一个空string是有效的input。

另外,请注意:ab可能是一个函数。