做前端开发的朋友应该都知道,js是一种弱类型的语言,这是我个人喜欢特别喜欢它的一个点,可能跟自己刚学编程的时候学的是java有关,总觉得强类型的语言约束太多。

(阅读的时候,文中的引号显示有些问题,不知道是编辑器的原因,还是数据库保存时的转换问题,怎么改都改不过来,请大家不要见怪,全部视为””即可)

但弱类型的语言也有个坏处,如果吃不透,有时候就会自己给自己挖坑。在js其中,”+” 号就特别需要注意,因为它就是典型的弱类型计算,存在隐性的值转换问题。对基础不扎实的同学,很容易造成一些意外的问题,比如 1 + 1 + “2” 和”1″ + 1 + 2 ,它们得到的结果是不同的。如果你知道还好,但如果你还存在怀疑的话,是时候补补课啦。

js中的加号,可用于字符串相加,数字相加,也可用于字符串和数字相加。可能你不知道的:js中的加号,可用于布尔值相加,对象相加,数组相加,只是这些类型进行相加的时候,有自己的加法规则。

今天,我们就一步一步的来理清js中的“加法”。

先从基础类型说起(也就是先抛开Object、Array和Function等引用数据类型的对象),就如前面提到的, 1 + 1 + “2” 和”1″ + 1 + 2 会出现不同的结果,为什么呢?因为都是相加,固然就不存在优先级的问题,所以问题在于字符串和数字的先后问题。

在js中,两个变量相加,如果两者都是数字,则会运用数学上的加法,即1+1等于2。但只要其中有一个不是数字,就会存在类型转换,比如:”2″+1。具体的转换规则如下:

1、当数字和字符串相加时,不分先后,两者都会转为字符串;

所以:”1″ + 2 和 1 + “2” 的结果都为 “12”

2、两者都是字符串时,为字符串相加;

3、当数字和布尔值相加时,布尔值转换为数字,再相加。其中,true转为数字的值为1,false转为数字的值为0;

所以:1 + true = 2,1 + false = 0

4、当字符串和布尔值相加时,布尔值转换为字符串,true为”true”,false为”false”;

所以:”a” + true = “atrue”,”a” + false = “afalse”

5、当布尔值和布尔值相加时,两者都转为数字再相加;

所以:false + true = 1,false + false = 0,true + true = 2

6、当 null 和数字、布尔值相加时,null 转为数字0,当 null 和字符串相加时,null 先转为字符串”null”,再相加;

所以:null + 1 = 1,null + true = 1(true为1),null + false = 0(false为0),null + “a” = “nulla”

7、当 undefined 和数字、布尔值相加时,因为 undefined 不能转为数字,所以结果永远是NaN ,当 undefined 和字符串相加时,先转为字符串”undefined”,再相加;

所以:undefined + 1 = NaN,undefined + true = NaN(true为1),undefined + false = NaN(false为0),undefined + “a” = “undefineda”

 

注意,上面有个奇怪的现象​,就是当字符串和数字相加时,得到的是字符串​。说明对于”+”操作符而言,字符串比数字优先级高​,可当我们只有布尔值,undefined和null进行”+”操作时,又会考虑转成数字,而不是字符串​。其实我们可以这样理解​:
对于”+”操作符而言,它会先尝试把两边的操作变量转换为数字,如果两边都转换成功,则进行数字加法。但当遇到一边字符串,一边数字时,字符串优先级更高,所以都转化为字符串再拼接​。

 

通过上面这几条规则的讲解,相信你对 1 + 1 + “2” 不等于”1″ + 1 + 2 也应该理解清楚了。

首先,对于 1 + 1 + “2” ,因为都是加法,所以不存在先后顺序,先计算  1 + 1,由于两者都是数字,所以 1 + 1 = 2,再计算2 + “2”,由上面的(1)可知,等于 “22”

然后对于”1″ + 1 + 2,先计算”1″ + 1,由(1)可知,等于”11″,再”11″ + 2,继续用(1)的规则,固然就得出了”112″

我们再拿”1″ + ( 1 + 2 )来举例,这次因为存在括号,有了先后顺序,所以很容易得出结果为”13″.

 

总结:

数字加数字,结果为数学上的相加,字符串”加”字符串,结果为字符串拼接,数字加字符串,结果为字符串拼接。
当布尔值,null 和 undefined 和数字”相加”时,会自动转换为数字,再相加,由于undefined不能转为数字,所以不论跟什么数字相加,结果都为NaN。
当布尔值,null 和 undefined 和字符串”相加”时,分别转换为对应的字符串,得到的结果再和字符串相拼接。
当布尔值,null 和 undefined 中的一个或多个进行”相加”时,先转换为各自对应的数字,再相加。

 

好了,此文先到这里,下文接着讲引用数据类型的“加法”。