Prettier: () in chained assignments

Created on 9 Oct 2017  路  3Comments  路  Source: prettier/prettier

Prettier 1.7.4
Playground link

--parser 
--no-semi
--trailing-comma 

Input:

foo = bar = 1

var foo = this.foo = 2

while (token = next()) {
}

Output:

foo = bar = 1

var foo = (this.foo = 2)

while ((token = next())) {}

Expected behavior:

Is there a reason for wrapping the assignment in parentheses in the latter two cases?
It looks like this was previously discussed in #1321.

Thanks! :-)

locked-due-to-inactivity question

Most helpful comment

For the var case, I believe the parens are there to show you that only the foo variable is decalared. I mean, it is a mistake to do var foo = bar = 0; if bar wasn't declared before. It _looks_ like _both_ variables are declared, but in reality only foo is. var foo = (bar = 0); helps explain that. I guess.

For the while case, it is a common convention to wrap assignment expressions in unnecessary parens if they appear where you'd normally expect a condition, to make it clear that you actually intend using assignment instead of comparison (and didn't just forget a couple of = signs). while (token === next()) {} vs while ((token = next())) {}.

I think everything works as intended, but I'll leave this open for more contributors to confirm.

All 3 comments

For the var case, I believe the parens are there to show you that only the foo variable is decalared. I mean, it is a mistake to do var foo = bar = 0; if bar wasn't declared before. It _looks_ like _both_ variables are declared, but in reality only foo is. var foo = (bar = 0); helps explain that. I guess.

For the while case, it is a common convention to wrap assignment expressions in unnecessary parens if they appear where you'd normally expect a condition, to make it clear that you actually intend using assignment instead of comparison (and didn't just forget a couple of = signs). while (token === next()) {} vs while ((token = next())) {}.

I think everything works as intended, but I'll leave this open for more contributors to confirm.

I prefer the wrapping to not; it's kind of like a warning, similar to what happens if you do this:

Prettier 1.7.4
Playground link

Input:

(function() {
  foo;
})()

(function() {
  bar;
})();

Output:

(function() {
  foo;
})()(function() {
  bar;
})();

The fact that prettier prints it this way gives you a hint that you wrote code that the engine will interpret differently than you expected (since you forgot a semicolon). So you fix it before running it, because you realize why it looks weird. This is a good UX. With the assignment operator, it's kind of the same thing:

Prettier 1.7.4
Playground link

Input:

let destroyAllHumans = false;
if (destroyAllHumans = true) {
  console.log("whoops! we should have just pulled in the three laws of robotics from npm");
}

Output:

let destroyAllHumans = false;
if ((destroyAllHumans = true)) {
  console.log(
    "whoops! we should have just pulled in the three laws of robotics from npm"
  );
}

So I think the fact that the double-paren stuff looks weird, and forces the user to stop and think about it, is actually providing a better UX than not, because I think this typo made from an assignment operator is more common than normal use of the assignment operator.

Okay. Thanks for clarifying! :-)

Was this page helpful?
0 / 5 - 0 ratings