Home > Article > Web Front-end > Understanding the “+” Operator in Javascript
We often see some "strange" statements on the Internet or in interview questions, such as
{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""
In Javascript, the +
operator is an overloaded operator that can be used to splice characters. string, and adding two "numbers". Which case is the case depends on the types of parameters on both sides of the operator.
We won’t encounter such troublesome things in daily development, but it’s always good to figure it out. In the specification, Balabala said a lot, which is simply:
1. For native types, as long as one of the parameters is a string, it will be processed by string concatenation, otherwise it will be processed by digital addition. Those that are not numbers will be converted into numbers first and then added.
The native types are: undefined, null, boolean, number, string.
Here are some examples:
0 + '1' // '01' null + 1 // 1 true + 1 // 2 false + 1 // 0 undefined + 2 // NaN, 因为undefined转成Number是NaN
2. For reference types, you need to convert them to native types first, and then add them according to the above rules. How to convert is detailed in the specification, but the specification seems a bit laborious. To put it simply: it is converted into a string by default. If you want to do something special, please override the valueOf()
method.
Let’s take an example:
function Complex(a, b) { this.a = a; this.b = b; } Complex.prototype.valueOf() { return this.a; } new Complex(2, 3) + new Complex(4, 5); // 6
But because Js does not support real operator overloading, that is, it cannot be added to obtain a custom type object, so the above example is rarely used in practical code.
But the current knowledge is enough to answer the original question. But wait, why is {}+[]
different from []+{}
? This is actually a grammatical issue. The former is equivalent to:
{} +[]
is actually two sentences, []
converted into a number is 0. It is easy to verify({}+[]) === '[object Object]'
+[] // 0
Someone may ask, what is new Date()
##valueOf() Isn’t it converted into a number? Why is the addition result still of string type?
Date is connected in string mode, but it will be converted into a number during comparison.
<,
>, so it is necessary to study it , the following js code roughly describes its behavior.
<pre class="brush:php;toolbar:false">/**
* @param input 即要转换的对象
* @preferredType 期望转换成的类型,可以是string或number
*/
function ToPrimitive(input, preferredType) {
if (typeof input !== 'object') {
return input; // 本来就是原生类型
}
var hint = preferredType || 'default';
if (typeof input['@@toPrimitive'] === 'function') { // @@toPrimitive是个内部方法,这里只是示例说明其工作原理
return input['@@toPrimitive'](input, hint); // 这就是为什么Date能特殊处理的原因
}
if (hint === 'string') {
return input.toString();
}
return input.valueOf();
}</pre>Please refer to the specifications for details
{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""In Javascript the
+ operator is an overloaded operator that can be used to splice strings and add two "numbers". Which case is the case depends on the types of parameters on both sides of the operator.
We won’t encounter such troublesome things in daily development, but it’s always good to figure it out. Balabala said a lot in the specification, which is simply:
0 + '1' // '01' null + 1 // 1 true + 1 // 2 false + 1 // 0 undefined + 2 // NaN, 因为undefined转成Number是NaN2. For reference types, you need to convert them to native types first, and then add them according to the above rules. How to convert is detailed in the specification, but the specification seems a bit laborious. To put it simply: it is converted into a string by default. If you want to do something special, please override the
valueOf() method.
function Complex(a, b) { this.a = a; this.b = b; } Complex.prototype.valueOf() { return this.a; } new Complex(2, 3) + new Complex(4, 5); // 6But because Js does not support real operator overloading, that is, it cannot be added to obtain a custom type object, so the above example is rarely used in practical code. But the current knowledge is enough to answer the original question. But wait, why is
{}+[] different from
[]+{}? This is actually a grammatical issue. The former is equivalent to:
{} +[]is actually two sentences,
[] converted into a number is 0. It is easy to verify
({}+[]) === '[object Object]'
+[] // 0Someone may ask, what is
new Date() ##valueOf()
Isn’t it converted into a number? Why is the addition result still of string type? <pre class="brush:php;toolbar:false">new Date().valueOf();
// 1491904757087
1 + new Date();
// "1Tue Apr 11 2017 18:02:16 GMT+0800 (CST)"</pre>
This is a special treatment for the Date class, @@toPrimitive. By default, the addition of
is connected in string mode, but it will be converted into a number during comparison. <pre class="brush:php;toolbar:false">new Date() < new Date(&#39;2018-01-01&#39;)
// true, 现在是2017</pre>
Converting reference types to native types is used in many operators, such as
, ></pre>
, so it is necessary to study it , the following js code roughly describes its behavior. <pre class="brush:php;toolbar:false">/**
* @param input 即要转换的对象
* @preferredType 期望转换成的类型,可以是string或number
*/
function ToPrimitive(input, preferredType) {
if (typeof input !== 'object') {
return input; // 本来就是原生类型
}
var hint = preferredType || 'default';
if (typeof input['@@toPrimitive'] === 'function') { // @@toPrimitive是个内部方法,这里只是示例说明其工作原理
return input['@@toPrimitive'](input, hint); // 这就是为什么Date能特殊处理的原因
}
if (hint === 'string') {
return input.toString();
}
return input.valueOf();
}</pre>