二元“+”运算符
二元加法运算符可以对两个数字做加法,也可以做字符串连接操作:
1 + 2 // 3
"hello" + " " + "there" // "hello there"
"1" + "2" // "12"
"1" + 2 // 12
1 + "2" // 12
二元“+”运算符的转换规则优先考虑字符串连接:
- 如果其中一个操作数是字符串或者转换为字符串的对象,另外一个操作数将会转换为字符串,加法将进行字符串的连接操作。
- 如果两个操作数都不是类字符串(string-like)的,那么都将进行算术加法运算。
从技术上讲,加法操作符的行为表现为:
- 如果其中一个操作数是对象,则对象会遵行对象到原始值的转换规则转换为原始类值:日期对象通过toString()方法转换,其他对象则通过valueOf()方法转换(如果valueOf()方法返回一个原始值的话)。由于多数对象都不具备可用的valueOf()方法,因此它们会通过toString()方法来转换。
- 在进行对象到原始值的转换后,如果其中一个操作数是字符串的话,另一个操作数也会转换为字符串,然后进行字符串连接。
- 否则,两个操作数都将转换为数字(或者NaN),然后进行加法操作。
1 + 2 // 2, 简单的加法
"1" + "2" // "12", 字符串连接
"1" + 2 // "12",数字转换为字符串后进行字符串连接
1 + {} // "1[object Object]",对象转换为字符串后进行字符串连接
2 + null // 2,null转换为0后做加法
2 + undefined // NaN,undefined转换为NaN后做加法
1 + true // 2,
1 + false // 1
1 + [] // "1"
1 + [2] // "12"
1 + [1, 2] // "112"
1 + { a: 1 } // "1[object Object]"
1 + function () {} // "1function () {}"
null + true // 1
null + undefined // NaN
true + {} // "true[object Object]"
false + {a:1} // "false[object Object]"
null + true // 1
null + false // 0
null + [] // "null"
undefined + [1] // "undefined1"
null + [1, 2] // "null1,2"
null + (new Date) // "nullSat Nov 05 2016 14:41:43 GMT+0800 (中国标准时间)"
null + function () {} // "nullfunction () {}"
true + true // 2,布尔值转换为数字后做加法
以上结果是在Windows 7 64bit上Google浏览器中得到的。
我的总结
- 两个操作都是数字,则进行加法运算
- 有一个操作数是字符串,则另外一个操作数转换为字符串,然后进行字符串连接。
- 一个操作数是数字,另外一个既不是数字,又不是字符串:
- 如果另外一个是原始值,则转换为数字,然后进行加法运算
- 如果另外一个是对象,则转换为字符串,然后时行字符串连接
- 如果两个都既不是数字,也不是字符串:
- 如果两个都是原始值,则都转换为数字,再进行加法运算
- 如果只有一个是原始值,另一个对象(函数、日期、数组或其他对象),则两个操作数都转换为字符串,再进行字符串连接
- 如果两个都是对象,同样都先转换为字符串,再进行字符串连接
具体转换规则,参考我的另一篇笔记《类型转换》。