javaScript-运算符及隐式类型转换

197 阅读7分钟

数学运算符的运算规则

数学运算符

+加、- 减、* 乘、/ 除、% 取模(求余数)++递增 --递减 + 正号 - 负号

加性操作符

加法和减法是加性操作符下面的两个运算符,与我们日常接触的数学中的加法减法是一样的,当然除此之外,他们也有另外一些比较特殊的地方。

- 加法

  • 当左右两侧的操作数,任何一侧为字符串,另一侧非字符串的类型则转为字符串,进行字符串的拼接。

  • 当左右两侧都为Number类型的情况下,按照如下规则返回结果:

    1. 左右两侧均为数值,执行常规的加法计算;
    2. 如果有一个操作数是NaN,则结果返回NaN;
  • 如果操作数是布尔值,undefined、null,则会(根据对应的规则)转为数字类型,然后再进行计算,如果其中转换结果为NaN,则结果就是NaN。

小测试题

var result = '1' + 2 + 3

- 减法

  • 当左右两侧都为Number类型的情况下,按照如下规则返回结果:

    1. 左右两侧均为数值,执行常规的减法计算;
    2. 如果其中一个操作数是NaN,则返回NaN;
  • 如果操作数是字符串、布尔值、undefined、null,则先会(根据对应的规则)转为数字类型,然后再进行计算,如果其中转换结果为NaN,则结果就是NaN。

减法为什么是加性操作符??

The - operator performs subtraction when applied to two operands of numeric type, producing the difference of its operands; the left operand is the minuend and the right operand is the subtrahend. Given numeric operands a and b, it is always the case that a–b produces the same result as a +(–b).

减号运算符作用于两个数字类型时表示减法,产生两个操作数之差。左边操作数是被减数右边是减数。给定操作数a和b,总是有a–b产生与a + ( -b )产生相同结果。

隐式类型转换规则

相信大家对复仇者联盟这个电影应该都不陌生,在电影中,每次遇到危险,钢铁侠就会主动变身,他就像我们在操作数据的时候,强制的类型转换,由我们自己主动控制。

但是在联盟中,还有一个没办法控制变身的人,就是绿巨人浩克,有些时候总是突然的就变身了,他就像我们JS中的隐式类型转换。

隐式类型转换:我们没有主动的对值进行转换,但是因为我们的某些操作引起JS自动帮我们进行转换,这样的转换是在JS内部自己实现的,

例如:

​ 使用加法运算符的时候,当有一侧的操作数为字符串,JS会自动把另一侧的操作数也转换为字符串,然后进行拼接

var a = '10' + 10; //1010

​ 使用减法运算符的时候,当有一侧的操作数不为数字,JS就会自动的把操作数转换为数字,然后进行计算

var b = '20' - 10; //10

那这些转换规则如何得知?

中文版参考网站 www.fengfly.com/document/EC…

ecma官网 www.ecma-international.org/ecma-262/5.…

乘性操作符

包含 乘法 ( * ) 除法 ( / ) 取模( % )

- 乘法操作符

  • 当左右两侧都为Number类型的时候,按照如下规则返回结果:
    1. 左右两侧均为数值,按照常规的乘法计算;
    2. 如果有一个操作数是NaN,则结果返回NaN;
  • 如果有一侧不是Number类型,则(根据对应的规则)转为数字类型,然后进行计算。
var result = '10' * '20'; // 200

- 除法操作符

  • 当左右两侧都为Number类型的时候,按照如下规则返回结果:
    1. 如果左右两侧均为数值,则按照常规的乘法计算;
    2. 如果是非零的有限数被零除,则结果返回 Infinity 或 -Infinity;
    3. 如果是零被零除,则返回NaN;
    4. 如果有一个操作数是NaN,则结果返回NaN;
  • 如果有一侧不是Number类型,则(根据对应的规则)转为数字类型,然后进行计算。
var resule = '10'/ 20 ;// 0.5

-取模操作符

❤数学题來啦~

爸爸给了你100元,让你去超市帮他买烟,看看能买多少,如果有剩下的,就都归你啦~一包烟30元,请问最多可以买几包?又剩余多少钱?

在这里我用的数字都比较简单,一共100元,30一包,100 / 30 = 3.3333333 ,但是售货员肯定不会0.3333这样卖给你

所以最终,我们能买到的最大数值,就是3,那么买完三包后,剩下的钱,就是我们的余数,剩下10元~那我就不客气的收下啦。

取模:进行除法计算,但是目的是为了得到余数,而不再是得到结果。

  • 如果左右两侧均为Number类型的时候,按照如下规则返回结果:
    1. 如果左右两侧均为数值,按照常规的除法进行计算,返回余数;
    2. 如果有一侧是NaN,则结果返回NaN;
    3. 如果除数为0,则结果返回NaN;
  • 如果有一侧不是Number类型,则(根据对应的规则)转为数字类型,然后进行计算。
var a = 10;
if(a % 2){
     alert("a存的是个奇数")
}else{
    alert("a存的是个偶数");
}

一元操作符

只能操作一个值的操作符叫做一元操作符。

- 一元加运算符

  • 如果操作数是Number类型的时候,正号放在数值前面,对其完全没有任何影响
  • 如果操作数是string、true、false、null、undefined,则(根据对应规则)转为数字类型。
var num = 5;
alert( +num ); //5

- 一元减运算符

  • 如果操作数是Number类型的时候,负号放在数值前面,表示负数。
  • 如果操作数是string、true、false、null、undefined,则(根据对应规则)转为数字类型。
var num = 10;
alert( -num );

巧妙利用隐式类型转换

我们偶尔可以利用隐式类型转换来达到我们想要将数据转化为另一种类型的目的。

var num = '123';
console.log(typeof +num);

var str = 123;
console.log( typeof (str + '') );

这种转换一般在已经可以明确想要的结果的类型的情况下使用。

递增和递减运算符

  • 前置型
var a = 10;
var b = 20;
++a; //11
--b; //19
  • 后置型
var a = 10;
var b = 20;
a++; //11
b--; //19

前置型,变量的值都是在语句被求值以前发生改变

var num = 10;
var num1 = ++num - 2; //9
var num2 = num - 2; //9

后置型,变量的值都是在语句被求值以后发生改变

var num = 10;
var num1 = num++ -2; // 8
var num2 = num - 2; //9
  • 当遇到Number类型时,如果是数值,直接进行计算。
  • 如果是string、null、undefined、false、true,则(根据对应规则)转换为数字类型后进行计算。

!!需要注意的一个大问题

在上述所有演示中,我们用到的都是整数,所以并看不出这个问题。实际上,在工作中我们经常还可能获取到一些带有小数的值。这样的值在计算的过程中,会产生一些我们无法理解的问题。

console.log(0.1 + 0.2); //0.30000000000000004

我们通过口算可以得出,结果应该是0.3,但是实际上,我们得到的结果却是0.30000000000000004。

这个问题的主要原因是基于IEEE754数值的浮点计算,ECMAScript并不是独此一家。很多其他的语言也存在这一的问题,感兴趣的同学可以研究下IEEE754,里面涉及的问题对于初学者不是很好理解。在这里就不过多解释。

解决方法

将小数转换为整数之后,进行计算,然后再转换回对应的小数。

var a = 0.1;
var b = 0.2;
console.log(  (0.1 * 10 + 0.2 * 10) / 10 ); //0.3

这样的方式尽管繁琐,但是可以有效的解决问题。