Search code examples
javascriptspecificationsreadability

Is this comparison behavior well-defined?


var x = 'foo';
var y = 'bar';

var isItDefined = (x !== (x = y)); // true, once
var isItAssigned = (x === 'bar'); // true

This idiom is handy for checking for immutability mutations with Immutable.js, ie

if (myMap !== (myMap = myMap.set('x', 2))) { changed.emit(); }

IIRC the immutable map implementation returns itself if the mutation results in no actual change.

Barring potential analysis of how ugly/'clever' this is, I'm curious if this is explicitly defined behavior in ES5+. Seems to depend on left-to-right evaluation, as the same structure expressed as

var thisWontWork = ((x = y) !== x);

does not ever evaluate to true.

Works in Chrome (40).


Solution

  • Yes, evaluation order is well defined in Ecmascript § 11.9.4. x !== (x = y) will get the value of x before assigning the value of y to x.