bublejs / buble

https://buble.surge.sh
MIT License
871 stars 67 forks source link

double parentheses on template strings #201

Open manferlo81 opened 5 years ago

manferlo81 commented 5 years ago

I am getting a double parentheses when using template strings.

The following is just a dummy example...

function logInvalid(obj) {
  console.log(`${obj} is not valid.`);
}

gets compile to...

function logInvalid(obj) {
  console.log((obj + " is not valid."));
}

I am not sure that's the intended behavior.

see the life example here

nathancahill commented 5 years ago

The added parentheses are to preserve the order of operations once the template string it compiled. The alternative is to do what Babel does: console.log("".concat(obj, " is not valid."))

Is this causing unexpected behavior?

manferlo81 commented 5 years ago

@nathancahill, I dont think it has to do with order of operation because there is no order to preserve in a single operator expression. It would apply in the following case...

console.log(`The result of the sum is ${5 + 2}.`);

I expect...

console.log("The result of the sum is " + (5 + 2) + ".");

But I am getting...

console.log(("The result of the sum is " + (5 + 2) + "."));

See here

Interestingly enough the "problem" disappears when I use concatenation and template string together, but we shouldn't have to do that...

console.log("The result of the sum is " + `${5 + 2}.`);

Also Babel is giving me the result I expect...

console.log(obj + " is not valid.");
// and
console.log("The result of the sum is " + (5 + 2) + ".");

Can you please explain on what situation this extra outer parentheses are useful?

Anyway I believe there is something going on here, have a look at the following...

const str = "string";
console.log(`here ${str} === ${"string"}`);

I am getting...

var str = "string";
console.log(("here " + str + " === " + ("string")));

Why the extra parentheses around the literal string (and around the whole expression) but not around the variable which evaluates to the same value?

See here

nathancahill commented 5 years ago

Parentheses are needed. See this simple example:

ES6

> var a = 'a'
> var b = 'b'
> `${a}${b}`.length
< 2

Transpiled without parentheses:

> a + b.length
< 'a1'

Transpiled with parentheses:


> (a + b).length
< 2
mourner commented 5 years ago

I guess this is more of a purity/redundancy issue — parentheses are needed when the template literal is a part of a more complex expression, but not e.g. when surrounded by parentheses already. But this really doesn't matter in the end because minifiers will strip this away.