【 Dmitri Pavlutin】细述Javascript的加法运算符
翻译:道奇 作者:Dmitri Pavlutin 原文:JavaScript Addition Operator in Details
简介
JavaScript是一门了不起的语言。我喜欢它的灵活性:只需以你喜欢的方式做事:更改变量类型,动态的给对象添加方法或属性,对不同的变量类型使用运算符等等。
然而动态是要付出代价的,开发人员需要知道针对不同操作符怎样处理类型转换:加号(+),等号(==和===),不等号(!=和!==)等等,许多运算符处理类型转换的方式是不一样的。
加法运算符
最常用的运算符:+,这个运算符用于接连字符串或对数字进行求和:
- 字符串连接:
var result = "Hello, " + "World!";
// 字符串 + 字符串 = 字符串 (连接)
// "Hello, World!"
- 数字算术相加:
var result = 10 + 5;
// 数字 + 数字 = 数字 (相加)
// 15
JavaScript允许使用对象,数组,null或undefined作为操作数。下面试着揭开转换的一般规则。
转换规则
使用下面的等式看一下在操作运算符里JavaScript是如何进行类型转换的:
- 如果至少有一个操作数是对象,它会被转换成原始值(字符串,数字或布尔);
- 转换之后,如果至少有一个操作数是字符串类型,第二个操作数会被转换成字符串,并且会执行连接。
- 在其他的情况下,两个操作数都会转换成数字并执行算数加法运算。
如果两个操作数都是原始类型,运算符会检查是否至少有一个是字符串类型,如果是就执行连接操作。其他情况就都转换为数字并求合。
对象类型转为原始类型
对象类型向原始类型的转换:
- 如果对象类型是Date,会调用该对象的
toString()
; - 其他情况下,如果
valueOf()
返回的是原始类型,会调用对象的valueOf()
; - 其他情况下(如果
valueOf()
不存在或没有返回原始类型),会调用toString()
方法,大部分情况下是用的这种转换。
当数组转换为原始类型,JavaScript会使用它的join(',')
方法,例如[1,5,6]就是"1,5,6"。普通JavaScript对像{}的原始类型是"[object Object]"。
学习例子
下面的例子帮助我们理解简单和复杂的转换场景。
例1:数字和字符串
var result = 1 + "5"; // "15"
解析:
1+"5"
(第二个操作数是字符串,基于规则2数字1变"1")"1"+"5"
(字符串连接)"15"
第二个操作数是字符串,第一个操作数从数字转换为字符串,然后进行连接。
例2:数字和数组
var result = [1, 3, 5] + 1; //"1,3,51"
解析:
[1, 3, 5] + 1
(使用规则1,将数组[1, 3, 5]转换成原始值: "1,3,5")"1,3,5" + 1
(使用规则2,将数字1转换为字符串 "1")"1,3,5" + "1"
(字符串连接)"1,3,51"
第1个操作数是数组,所以它被转换为原始字符串值,在下一步数字操作数转换为字符串,然后再完成两个字符串的连接。
例3:数字和布尔类型
var result = 10 + true; //11
解析:
10 + true
(基于规则3将布尔值true转换成数字1)10 + 1
(将两个数字求值)11
因为两个操作数都不是字符串,布尔值转换成数字,然后执行算术的求和。
例4: 数字和对象
var result = 15 + {}; // "15[object Object]"
解析:
15 + {}
(第二操作数是个对象,应用规则1将对象转换为原始类型字符串"[object Object]")15 + "[object Object]"
(使用规则2将数字15转换成字符串 "15")"15" + "[object Object]"
(字符串连接)"15[object Object]"
第二个对象操作数转为字符串值,因为valueOf()
方法返回对象本身,它不是原始值,toString()
方法就会被调用并返回字符串,第二个操作数现在是字符串了,因此数字也被转换为字符串,最后执行两个字符串的连接。
例5: 数字和null
var result = 8 + null; // 8
解析:
8 + null
(因为两个操作数都不是字符串,基于规则3将null转为数字0)8 + 0
(数字相加)8
因为操作数不是对象也不是字符串,null被转换成数字,然后计算数字的和。
例6: 字符串和null
var result = "queen" + null; // "queennull"
解析:
"queen" + null
(因为第一个操作数是字符串,基于规则2将null转成字符串"null")"queen" + "null"
(字符串连接)"queennull"
因为第一个操作数是字符串,null转成字符串,然后进行字符串连接。
例7: 数字和undefined
var result = 12 + undefined; // NaN
解析:
12 + undefined
(因为操作数都不是对象或字符串,基于规则3将undefined转为数字NaN)12 + NaN
(数字相加)NaN
因为操作数都不是对象或字符串,undefined转为数字:NaN,对数字和NaN进行相加求值等于NaN.
可以在JsBin中看这些例子
总结
为了避免潜在的问题,不要对对象使用加法运算符,除非你清楚的定义了toString()
或valueOf()
方法。正如例子中所看到的,加法操作符有很多特定的情况。了解确切的转换场景能帮你避免未来的意外,祝coding愉快!
转载自:https://juejin.cn/post/6844903968196263950