Are these lines of JavaScript code equivalent?

JavascriptIf Statement

Javascript Problem Overview


I've found this string in JavaScript code.

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

This is a shorthand of an if-else statement, however the value null is assigned if it is null. Isn't that ALWAYS equivalent to

var c = a.b

including all cases - exceptions, null, undefined, etc?

In another words, are these lines (always) equivalent?

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

-vs-

var c = a.b

Javascript Solutions


Solution 1 - Javascript

No, they AREN'T NECESSARILY EQUAL always if b is a getter that updates a variable. It's bad practice to code this way though

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);

Solution 2 - Javascript

These statements are logically equivalent.

That being said, and as mentioned in another answer, if a.b has side effects, the statements will not result in the same program state.

This could be readily obvious in the form of var c having a different value depending on which of these statements are executed, or more hidden, if a.b modifies something elsewhere in the program.

Refactoring

As refactoring has been discussed, I'll touch on it briefly. As the above has hopefully made obvious, directly refactoring would not be safe in all scenarios. However, I would still recommend a refactor of one kind or another.

The two possible situations as I see them are:

  1. a.b has no side effects, direct refactoring is safe
  2. a.b has hidden side effects. This represents very unclear, confusing, and just downright bad code. It should be refactored so that all changes happening during the statement are clear and obvious to a reader (hopefully intuitively so, as well as supported by comments).

Solution 3 - Javascript

As @potatopeelings already pointed out, the two possible statements are not always equivalent, since one can write obscure code, which will have different results.

However, if I see a code, like

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

I will assume that the code's intention is

var c = a.b;

so I will change it to make the code prettier. If I will be negatively surprised, that is, the code does not pass the testing phases due to this change, then I will try to find the author of a.b with git blame.

So, my answer is, that the two statements are not equivalent, but should be equivalent in well-written code.

Solution 4 - Javascript

Well, actually not even

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

is guaranteed to be equivalent to

var c = a;

when a is resolved by a getter or an ES6 proxy handler on the global object.

Hence for instance, this assign to c the value 0:

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

while this assigns to c the value 1:

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

Solution 5 - Javascript

You're right, var c = a.b is exactly the same as var c = (a.b !== null) ? a.b : null;

My guess is the null in the ternary operator was meant to be anything except null, a default value if you will.

Solution 6 - Javascript

The reason for that confusingly odd syntax is because a.b might be an empty string OR undefined, and apparently an empty string is valid input.

Also, note: a.b might be a function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHaradzieniecView Question on Stackoverflow
Solution 1 - JavascriptpotatopeelingsView Answer on Stackoverflow
Solution 2 - JavascriptRiverView Answer on Stackoverflow
Solution 3 - JavascriptLajos ArpadView Answer on Stackoverflow
Solution 4 - JavascriptGOTO 0View Answer on Stackoverflow
Solution 5 - JavascriptStyphonView Answer on Stackoverflow
Solution 6 - JavascriptdwozView Answer on Stackoverflow