这几行JavaScript代码是等价的吗?

Are these lines of JavaScript code equivalent?

本文关键字:代码 JavaScript 几行      更新时间:2023-09-26

我在JavaScript代码中发现了这个字符串。

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

这是if-else语句的简写,但是如果值为空则赋值为null。ALWAYS不等于

吗?
var c = a.b

包括所有情况-异常,null,未定义等?

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

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

var c = a.b

不,如果b是更新变量的getter,它们不一定总是相等的。通过

这样编码是不好的做法。
var log = 0;
var a = {
    get b() {
        log++;
        return log;
    }
}
var c = (a.b !== null) ? a.b : null;
// outputs 2
console.log(c);
var log = 0;
var a = {
    get b() {
        log++;
        return log;
    }
}
var c = a.b;
// outputs 1
console.log(c);

这些语句在逻辑上是等价的。

话虽如此,正如在另一个答案中提到的,如果a.b有副作用,语句将不会导致相同的程序状态。



如果a.b修改了程序中的其他部分,则var c根据执行哪条语句具有不同的值,或者更加隐藏,这很明显。

重构

既然已经讨论过重构,我将简要地介绍一下。如上所述,直接重构在所有情况下都不是安全的。然而,我仍然会推荐这样或那样的重构。

我认为有两种可能的情况:

  1. a.b没有副作用,直接重构是安全的
  2. a.b有隐藏的副作用。这代表着非常不清楚,令人困惑,和彻头彻尾的坏代码。它应该被重构,以便所有语句中发生的变化是清晰和明显的读者(希望是直观的,以及支持的评论)。

正如@potatopeelings已经指出的那样,这两种可能的语句并不总是等价的,因为一个人可以编写晦涩的代码,这将产生不同的结果。

但是,如果我看到一个代码,比如
var c = (a.b !== null) ? a.b : null;
我将假设代码的意图是
var c = a.b;

,所以我将改变它,使代码更漂亮。如果我感到消极的惊讶,也就是说,由于这个变化,代码没有通过测试阶段,那么我将尝试找到a.b的作者与git的责任。

所以,我的答案是,这两个语句并不等价,但在编写良好的代码中应该是等价的。

实际上,甚至

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

保证等于

var c = a;

a被全局对象的getter或ES6代理处理程序解析时。

因此,这给c赋值0:

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

同时给c赋值1:

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

你是对的,var c = a.bvar c = (a.b !== null) ? a.b : null;是完全一样的

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

这种令人困惑的奇怪语法的原因是a.b可能是空字符串或未定义,显然空字符串是有效的输入。

同时注意:a.b可能是一个函数