Por que o JavaScript manipula os operadores de mais e menos entre strings e números de maneira diferente?

Eu não entendo porque o JavaScript funciona dessa maneira.

console.log("1" + 1); console.log("1" - 1); 

A primeira linha imprime 11 e a segunda imprime 0. Por que o JavaScript manipula o primeiro como uma String e o segundo como um número?

A concatenação de strings é feita com + então o JavaScript irá converter o primeiro numérico 1 para uma string e concatenar “1” e “1” fazendo “11”.

Você não pode executar subtração em strings, então Javascript converte o segundo “1” em um número e subtrai 1 de 1, resultando em zero.

+ é ambíguo. Pode significar “concatenar” ou “adicionar”. Já que um lado é uma corda, é entendido como “concatenar”, daí o resultado é 11 (que, aliás, era uma das minhas piadas favoritas quando criança. Isso e “1 + 1 = janela”, como mostrado visualmente: │┼│ ニ ⊞ )

- no entanto, tem apenas um significado: subtrair. Então subtrai.

Esse tipo de problema não está presente em outras linguagens como o PHP, onde “concatenar” é . em vez de + , sem fazer ambiguidade. Ainda outras linguagens como o MySQL não possuem um operador de concatenação, ao invés disso usam o CONCAT(a,b,c...) .

Porque a especificação explicitamente diz para fazer isso. Página 75. Observe a diferença entre 11.6.1 etapas 5-8 e 11.6.2 etapas 5-7.

11.6.1 – descreve como o operador de adição funciona

1-4 . …

5 Vamos lprim ser ToPrimitive (lval).

6 Seja rprim ToPrimitive (rval).

7 Se Type (lprim) for String ou Type (rprim) for String, então

7a . Retorna a String que é o resultado da concatenação de ToString (lprim) seguida por ToString (rprim)

8 Retornar o resultado da aplicação da operação de adição para ToNumber (lprim) e ToNumber (rprim)

11.6.2 – descreve como funciona o operador de subtração

1-4 . …

5 Deixe que seja ToNumber (lval).

6 Seja rnum ToNumber (rval).

7 Retornar o resultado da aplicação da operação de subtração para lnum e rnum

Resumo Em caso de adição, se qualquer um dos operandos, quando convertidos em valores primitivos sem quaisquer sugestões, se tornar subitamente uma string, o segundo também será convertido em uma string. Em caso de subtração, ambos os operandos são convertidos em um número.

+ é um operador de adição para variables ​​numéricas e um operador de concatenação para cadeias de caracteres.

Sempre que houver uma string após um + , o Javascript escolherá usar o + como um operador de concatenação e converter (typescript) tantos termos quanto possível ao redor da string, para que possa concatená-los. Esse é apenas o comportamento do Javascript. (Se você tentou console.log(23 + 2 + "." + 1 + 5 + "02" + 02); você obterá o resultado 25.15022 . O número 02 foi typescript na string 2 antes de ser concatenado.

- só pode ser um operador de subtração , então, quando recebe uma string, ela implicitamente muda o tipo da string "1" para 1 numérico; se não fizesse isso, não há como "1" - 1 faria sentido. Se você tentou o console.log(23 + 2 + 1 + 5 - "02" + 03); você terá 32 – a string 02 será convertida no número 2 . O termo após o - deve poder ser convertido em um número; se você tentou console.log(23 - 2 - "." - 1 - 5 - 02 - "02"); você receberá NaN retornado.

Mais importante, se você tentou console.log(23 + 2 + "." + 1 + 5 - "02" + 03); , resultará 26.15 , onde tudo antes - foi tratado como uma string (porque contém uma string "." , e depois o termo depois de - é tratado como um número.

Não há operador de concatenação de cadeia dedicada em JavaScript **. O operador de adição + realiza concatenação ou adição de strings, dependendo do tipo de operandos:

 "1" + 1 // "11" 1 + "1" // "11" 1 + 1 // 2 

Não há oposto de concatenação (eu acho) e o operador de subtração - somente realiza subtração independentemente do tipo de operandos:

 "1" - 1 // 0 1 - "1" // 0 1 - 1 // 0 "a" - 1 // NaN 

** O. O operador em PHP e o operador & em VB são operadores de concatenação de cadeias dedicadas.

De acordo com o padrão EcmaScript 262. Os operadores + e - se comportam de maneira diferente quando as strings estão envolvidas. O primeiro converte todos os valores em uma string. O segundo converte todos os valores em um número.

Do padrão:

Se Type (lprim) for String ou Type (rprim) for String, então Return the String é o resultado da concatenação de ToString (lprim) seguido por ToString (rprim)

Esta regra implica que, se na expressão houver um valor de string, todos os valores envolvidos na operação + serão convertidos em uma string. Em JavaScript, quando o operador + é usado com strings, ele é concatenado. É por isso que console.log("5"+1) retorna “51”. 1 é convertido em uma string e, em seguida, “5” + “1” são concatenados juntos.

No entanto, a regra acima não se aplica ao operador - . Quando você está usando um - todos os valores são convertidos em números de acordo com o padrão (veja abaixo). Portanto, nesse caso, "5" é convertido em 5 e, em seguida, 1 é subtraído.

Do padrão:

5 Deixe que seja ToNumber (lval).

6 Seja rnum ToNumber (rval).


Definição de operador do padrão EcmaScript 262.

Operador + : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 Operador + definição

Operador – : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2 Operador - definição