加法运算符(+)是最常见的运算符,用来求两个数值的和。
在两个操作数都是数字的时候,会做加法运算
2+4
两个参数都是字符串或在有一个参数是字符串的情况下会把另外一个参数转换为字符串做字符串拼接
"2"+"4" 拼接为"24".
2+"4" 拼接为"24".
在参数有对象的情况下会调用其valueOf或toString
优先使用valueof方法
如果运算子是一个Date对象的实例,那么会优先执行toString方法。
空对象拼接字符会显示[object Object]+字符
在只有一个字符串参数的时候会尝试将其转换为数字
+"3000" //3000
非数字字符转换为NaN
在只有一个数字参数的时候返回其正数值
js中加号+ 运算符可以用在一元运算 与 二元运算1, 一元运算请况
语法: + Expression
+'号运算符作为一元运算符时,Expression将进行 ToNumber() 操作
经常使用 +a 类似的形式对变量a进行类型转换 ,如下:
const a = '1'
+a // 输出为1 (变为number类型);
ToNumber( argument )转换方式:
Undefined: return NaN,
Null:return +0,
Bollean: true return 1,false return 0,
Number: return value
String: 若字符串为纯数字时返回转换后的数字;非纯数字返回NaN
Symbol 抛出 TypeError 异常
Object 进行以下步骤:
1.先进行ToPrimitive(argument, hint Number)得到rs; 2.然后返回 ToNumber(rs)的结果。
语法: ToPrimitive ( input [, PreferredType] )
参数:
①参 input :传入的值。
②参数 PreferredType :可选,需要被转换的类型。 '+'加号作为一元运算符时,此值为“number”;而作为二元运算符时,未传递此值,以默认的“default”代替。
2. 二元运算符
2.1 解析步骤
简单概括为下面4个步骤:
1) 值进行GetValue()操作。
2) 值进行ToPrimitive()操作,
3) 若一方为String类型,2个值都进行ToString()转换,最后进行字符串连接操作。
4) 若都不是String类型,2个值都进行ToNumber()转换,最后进行算数加法运算。
2.2.1 方法签名
语法: ToPrimitive ( input [, PreferredType] )
参数:
①参 input :传入的值。
②参数 PreferredType :可选,需要被转换的类型。'+'加号作为一元运算符时,此值为“number”;而作为二元运算符时,未传递此值,以默认的“default”代替。
2.2.2 解析说明
ToPrimitive()的详细解析过程可以看这里:
http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive
简化为以下步骤:
( PreferredType是为 非基础类型 决定是优先使用valueOf方法还是toString方法,对基础类型无效),指定为number优先使用valueOf方法,指定string,优先使用toString方法
1) 若input类型为原始值(如:Undefined、Null、Boolean、Number、String、Symbol),直接返回input的本身 。 直接忽略 PreferredType
2) 若input类型为object(如:Array、Object、Date),将根据第②个参数 PreferredType 的值进行以下操作:
就像之前讲的,'+'加号作为一元运算符时, 传递参数 PreferredType 的值为“number”;而作为二元运算符时,未传递此值时以默认的“default”代替。
在上面的图中,只看到 PreferredType 的值为“number” 或 “string” 时才进行解析,那么默认的“default”表示什么呢?
ps: Date类型内部重写了@@toPrimitive()方法,将“default”设置为“string”,而其他内置的对象都将“default”设置为“number” 。
Date.prototype[@@toPrimitive]:
http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive
2.3 示例
1) String + String
说明:进行字符串连接操作
'a' + 'b'// =>'ab'
'1' + '2'// =>'12'
2) Number + Number
说明:进行算数的加法操作
1 + 2// =>3
3) Number + String or String + Number
说明:Number类型的值先进行ToString()转换,随后再与另一个String类型的值进行拼接操作
1 + '0'// =>'10'
1 + '0a'// =>'10a'
'1' + 2// =>12
4) Array + String or Array + Number
说明:Array类型进行ToPrimitive()转换时,先执行valueOf(),因其返回一个object类型的值,所以又执行了toString()方法。
var tmpList = ['a', 'b', 'c']
tmpList.valueOf()// =>["a", "b", "c"] 输出自身
tmpList.toString()// a,b,c
// 1.Array + String
tmpList + 'd'// =>a,b,cd
// 2.重写Array的valueOf()方法,使其返回一个非object
Array.prototype.valueOf = function (e) {
return this.join('-')
}
tmpList + 'd'// =>a-b-cd
5) Date + String or Date + Number
说明:上面已经讲过,Date类型重写了ToPrimitive(),所以先调用toString(),若返回值为object,再调用valueOf()。
var dt = new Date()
dt.valueOf()// =>1503501745901
dt.toString()// Wed Aug 23 2017 23:22:25 GMT+0800 (中国标准时间)
// 1.Date + String : dt直接使用了dt.toString()方法
dt + 'd'// =>Wed Aug 23 2017 23:22:25 GMT+0800 (中国标准时间)d
// 2.重写Date的toString()方法,使其返回一个object的值
Date.prototype.toString = function (e) {
return { year: this.getFullYear() }
}
// 略过了 dt.toString(),调用了 dt.valueOf()
dt + 'd'// =>1503501745901d
End
var i = 1var j = 2
alert(i+0+j) 结果 alert:3.
现在解答为什么要加一个0.因为在js里面,如果你直接写+号的话,JS会以为你是把两个字符串相加,就像上面的,结果会alert(12),而加上一个0的话,会让它知道这个是在做一个加法运算而不是拼接字符串。当然