学习JavaScripts第二站:JavaScript编程中的加减乘除

学而时习之,不亦乐乎。

既然我们要运用javascript来操纵不同的数据,那么运算就是无论如何也绕不过去的一关,那今天我们就来学习如何在JavaScript这门语言里进行运算。

按照常识,只有数字才可以参与运算,然后在编程的世界里,所有的数据类型都可以参与运算!

接下来我们先学习数字的运算:

加法

其实

  • Number:数字的加减乘除:

    • 加法talk is cheap,show me your code(不多哔哔,直接上代码):

    JavaScript里直接使用’+'来进行加法运算

    //声明变量a和b,分别储存两个数字
    var a = 1
    var b = 2
    //加法运算
    console.log(a + b)//3
    /*	
    	加号的左边和右边分别写上一个值就ok了,上边我们声明了两个变量,对他们进行了一次加法运算,在控制台里打印了3,我们去打印一下a和b看看加法运算之后他们分别发生了什么变化
    */
    console.log(a)//1
    console.log(b)//2
    /*结果是不是和大家想的完全一样,a和b的值并没有发生变化,我们把a和b加起来得到了一个新的数据3,这并不会影响a和b的值,如果我们想要保存运算出来的值,我们需要额外声明一个变量保存*/
    var c = a + b
    console.log(c)//3,这次运算后的结果被保存了下来。
    //可是有的同学会觉得很麻烦,1+2=3这么一个简单的操作,我缺需要声明三个变量,当然如果我们明确的知道想要进行运算的两个数字可以直接
    var d = 1 + 2
    console.log(d)//3
    

    ​ 这时候有的同学安奈不住了,老子花了近万元大洋就是来听你讲1+2=3的?非也,非也,我们来看点儿小学里没有学过的加法操作 -> ++(递增也叫做自增)[这个有一个学名叫操作符即完成某个操作的符号]:

    //接下来我们来看看什么是递增操作
    //首先声明一个变量保存一个数字
    var e = 1
    e++
    console.log(e)//2
    //e++表示的是 e = e + 1,我们给变量e重新赋值,新值为1+1=2,现在是不是对自增一下子理解了,我们在用加法进行运算的时候并不会改变这个变量本身保存的值,而用自增的时候他真的改变了自己!!!
    //++不但可以写到变量的前边也可以写到变量的后边
    var f = 1
    ++f
    console.log(f)//2
    

    ++既可以写在变量的前边也可以写在变量的后边,不同的写法在参与计算的时候会得到不同的结果:

    var g = 1
    var h = 1 + g++
    console.log(h)//2,!!!!,刚刚说g++表示的是 g = g + 1也就是2,1+2=2?其实不是,先打印一下g
    console.log(g)//2 g是2没错,那1+2怎么可能等于2呢?
    

    ​ 原因是我们把递增++写在变量g的后边,这样写,变量g在参与运算的时候不会先+1在参与运算,而是先参与运算再+1

    ​ 接下来我们把++写在变量的前边看会有什么效果:

    var i = 1
    var j = 1 + ++i//这样写看上去很别扭,所以一般会写成 ++i + 1,两者的结果是一样的
    console.log(j)//3
    

    ​ 当我们把++写在变量i的前边时,在++i参与计算时会先自增1,再参与计算。

    总结++(递增),作用是让数字在原来的基础上+1,当++出现在运算里时,如果写在变量的前边,这个变量会先递增再参与运算,如果写在变量的后边,会先计算再递增。

    • 减法

    JavaScript里的减法结果和显示中的结果一模一样。

    JavaScript里直接使用’-'来进行加法运算

    var num_a = 2
    var num_b = 1
    console.log( num_a - num+b )//1
    console.log( num_a, num_b )//2 1,运算并不会改变变量原来的值,而是会重新返回一个值,加入我们需要这个值的话就重新声明一个变量保存起来。
    var num_c = num_a - num_b
    console.log(num_c)//1
    var num_d = 1
    var num_e = 2
    console.log( num_d - num_e )//-1
    

    ​ 和加法一样,js里运算减法的另外一个操作符是--(递减也叫做自减):

    var some_number = 123
    some_number--
    console.log(some_number--)//122
    //上边的运算的背后操作是这样的:
    //some_number = some_number - 1//123 - 1 = 122
    //和++操作符一样,--除了可以写在变量的后边之外也可以写在变量的前边
    --some_number
    console.log( some_number )//121
    

    --(递减或递减)操作符的顺序在参与运算的时候也会因为位置的不同而产生不同的结果:

    var num_one = 5
    var num_two = 3
    console.log( num_one - num_two )//2
    console.log( num_tow )//2,num_two的值并没有发生变化
    console.log( num_one - num_two-- )//2
    console.log( num_two )//2,num_two发生了一次自减操作,3-1=2
    

    num_two在参与运算的时候--操作符写在变量的后边,那么先进行运算,再对num_two进行自减。

    var num_three = 5
    var num_four = 3
    console.log( num_three - --num_four )//3
    

    --写在num_four的前边,那么在进行运算之前变量会先进行一波自减的操作,再参与运算。

    小总结

    --自减和++操作符[即进行某项操作的符号]在参与运算时,出现在变量前边,就会先进行自减或者自增,写在变量后边,就会先进行自增或者自减然后再参与运算。

    • 乘法

    JavaScript中的乘法使用*操作符。在进行数字和数字的运算时结果和现实中的乘法结果一样。

    var a = 1
    var b = 0
    console.log( a * b )//0
    var some_a = 1
    var some_b = -1
    console.log( some_a * some_b )//-1
    
    • 除法

    JavaScript中的乘法使用*操作符。在进行数字和数字的运算时结果和现实中的乘法结果一样。

    var num_a = 5 
    var num_b = 10
    console.log( num_a / num_b )//0.5
    

    ​ 这里要注意一下,乘法和除法并没有所谓的**//操作符,那么在了解了加减乘除的操作之后,我们来玩一个好玩的操作:浮点数的运算:

    var a = 0.1
    var b = 0.2
    console.log( a + b )//0.30000000000000004
    console.log( a * b )//0.020000000000000004
    

    ​ What?!!0.1+0.2不等于0.3?是的你没有看错!就是这么邪!

    因为JavaScript使用的是IEEE74双精度浮点数来储存数字,双精度浮点数用来做运算的时候会遇到这种问题,不单单是JS所有使用这种方法来储存数字的语言都有这个缺点。

    ​ 既然问题出来了,我们如何去解决呢?请听题:

    我在做一个电商网站,商品的价格必然有小数点,我该怎么办呢?

    ​ 对于这个问题我们当然有解决的方案,钱一般只算到小数点后两位,比如:1.23表示这个商品的价格是一块二毛三,直接用1.23去进行运算必然会有很很很很很很很小的误差,误差虽然小但是我们要的是精确,那么我们只需要:

    var c = 0.11
    var d = 0.22
    console.log( (c*100 + d*100) / 100 )// 0.33 这下我们的问题是不是就完美的解决了呢!
    

    ​ 刚才我们使用了一个括号,这个括号和数学中学过的括号作用一样,是为了改变运算顺序的,是为了保证先运行加法在运行除法:

    var e = 5
    var f = 6
    //我们想先计算e-f把得到的结果再乘以100
    var g = e - f
    console.log( g * 100 )//-100 这样做虽然能得到结果,但是很麻烦,只需要像小学一年级学过的使用一个括号就能搞定
    console.log( (e - f) / 100 )//-100
    

    ​ 到此,数字的加减乘除已经学完了,什么?你还要学求幂运算?稍安勿躁这个我们后边再讲,接下来我们要学习的是其他数据类型的运算。

    纯字符串的加法运算:

    var str_a = '5'
    var str_b = '5'
    console.log( str_a + str_b )//'55'
    

    ​ 字符串在进行加法运算时会把两个字符串合为一个字符串,这种情况叫做字符串拼接,因此:

    var str_c = '八级'
    var str_d = '大狂风'
    console.log( str_c + str_d )//'八级大狂风'
    

    其他数据类型与字符串的加法运算:

    数字

    任何数据类型的数据与字符串相加,都会被转化为字符串然后在进行拼接。转化成字符串使用的是toString方法。

    var a = '5'
    var b = 5
    console.log( a + b )//'55'
    

    ​ 上边浏览器在计算变量ab的加法时发现变量a是一个字符串,于是不管另一个变量是什么类型的数据,都会用toString方法(函数)把他转化为字符串再与变量a拼接起来。

    这种把一种数据类型转化为另一种数据类型再进行运算的情况叫隐式数据类型转化。隐式数据类型转化即偷偷的把一种数据类型转化为了另一种数据类型,原因是:不同数据类型无法进行运算。

    //上边的操作相当于
    b.toString()//把变量b转化为字符串,结果为'5',然后把两个字符串拼接成'55'
    

    null & undefined

    var a = '5'
    var b = 'null'
    var c //变量c在声明的时候没有赋值,则值默认为undefined
    console.log( a + b )//'5null',null被转化为了字符串'null'
    console.log( a + c )//'5undefined',undefined被转化为了字符串'undefined'
    

    Object & Array

    var str = '5'
    var a = {}
    var b = {a: 1 , b: 2}//对象里的a和b是对象的属性,并不是变量a和b
    //对象里不管有没有值用toString方法转化为字符串时都时"[object Object]",因此结果是显而易见的:
    console.log( str + a )//"5[object Object]"
    console.log( str + b )//"5[object Object]"
    
    var str = '5'
    var c = []
    var d = [1, 2, 3]
    console.log( str + c )//'5',没有储存任何数据的数组被转化成了空字符串,更详细的知识在第二站的课件里
    console.log( str + d )//'51,2,3'
    

    ​ 我们都知道数组和对象里可以存储任意类型的数据,因此:

    var str = '5'
    var a = [1, '5', {name: '小明', age: 18}]
    console.log( str + a )//"51,5,[object Object]"
    var b = {  a: 1, b: [1, 2, 3] }
    console.log( str + b )//"5[object Object]"
    

    总结 :在进行加法运算的时候,字符串就是爹,任何数据类型见了他都得转为字符串再拼接。

    字符串的减法运算:

把所有的数据类型都转成数字。

var a = '4',
    b = 3
console.log( a + b )//'43'
console.log( a - b )//1
console.log( b - a )//-1

​ 上边我们对a+ba-b做了一个对比,a+b得到的结果是一个字符串,a-b得到的结果是一个数字,这里在运行减法运算的时候,浏览器悄悄的用Number()帮我们把字符串'4'转化成了数字4(隐式类型转化),因此得到的结果是1

​ 我们都知道把字符串转为数字的方法里除了Number还有parseInt()parseFloat()吗?那它到底用的是哪个来转的?

var str_a = '2helloworld',
    num_a = 1
console.log( str_a - num_a )//NaN,任何数字和NaN运算得到的结果都是NaN
console.log( Number(str_a)// NaN
console.log( parseInt(str_a) )//2
console.log( parseFloat(str_a) )//2

​ 答案是不是显而易见?隐式类型转化的时候使用的是Number()

​ 上边我们用字符串减一个数字,或者用数字减去一个字符串,浏览器把字符串转化为了数字,那么如果是字符串减字符串呢?还会转换吗?

var str_a = '4',
    str_b = '3'
console.log( str_a - str_b )//1

​ 我们发现即便是两个字符串参与减法运算也会把他们转化为数字。

​ 那么接下来的情况是不是结果一眼就能确定了:

var a = undefined,
    b = null,
    c = 1
console.log( c - a )//NaN
console.log( c - b )//1
//这里我们回忆一下,上边学的内容
console.log( Number( a ) )//NaN
console.log( Number(b) )//0

​ 上边我们列举的都是简单的数据类型,接下来我们看看复杂的数据类型会不会转成数字呢?

var obj_a = { name: 'xiaoming', age: 18 },
    obj_b = {},
    arr_a = [1, 2, 3],
    arr_b = [],
    str = '123',
    num = 5
//我们先来看看数字和对象的运算
console.log( num - ojb_a )//NaN
console.log( num - ojb_b )//NaN
//这里我们可能会这样想:不管是空对象还是有内容的对象,调用Number()方法得到的结果都是NaN,任何一个数字和NaN运算得到的结果都是NaN。实则不然,这里在对对象进行隐式类型转换时分了两步走:
//第一步,对对象调用toString()方法
console.log( obj_b.toString() )//"[object Object]"
console.log( obj_a.toString() )//"[object Object]"
console.log( Number("[object Object]") )//NaN
console.log( 5 - NaN )//NaN
//上边的才是运行减法时一个完整的过程!先转字符串,字符串再转数字,最后进行运算。
//那么接下来我们看看数组
console.log( num - arr_a )//NaN
console.log( num - arr_b )//5

​ 接下来我们对完整的过程进行一个还原:

//arr_a => [1, 2, 3]
console.log( arr_a.toString() )//"1,2,3"
console.log( Number( "1,2,3" ) )//NaN
console.log( 5 - NaN )//5
//arr_b => []
console.log( arr_b.toString() )//""
console.log( Number("") )//0
console.log( 5 - 0 )//5

​ 即便是字符串和对象运行减法也是同样的结果:

var str = '123',
    arr = [],
    obj = {}
console.log( str - arr )//123
console.log( str - obj )//NaN

​ 推理过程和上边的一模一样,这里一定要自己推理一遍哦!

​ 八字真言记心中:遇到减号全转数字

最后我们来看看乘法和除法

乘法和除法依旧是数字为王,不管什么全转数字!

​ 简单数据类型,直接用Number()转[下边的例子以数字为例,字符串可以得到相同的结果]:

var a = 1,
    b = '2',
    c = '2hello',
    d = '2'
console.log( a * b )//2
console.log( a * c )//NaN
console.log( b * d )//4

​ 过程还原:

//b
console.log( Number(b) )//2
console.log( 1 * 2 )//2
//c
console.log( Number(c) )//NaN
console.log( 1 * NaN )//NaN
//d
console.log( Number(b), Number(d) )//2, 2 
console.log( 2 * 2 )//4

undefinednullBoolean

var a = 2,
    b,
    c = null,
    d = true,
    e = false
console.log( num * b )//NaN ,Number()把undefined被转为了NaN
console.log( a * c )//0 Number()把null转化为了0
console.log( a * d )//2 Number()把true转化为了1
console.log( a * e )//0 Number()把false转化为了0

​ 接下来我们看看对象的乘法运算时怎么样的:

var obj_a = {},
    obj_b = {name: 'xiaoming', age: 18},
    arr_a = [],
    arr_b = [1, 2, 3],
    a = 2
console.log( a * obj_a )//NaN
console.log( a * obj_b )//NaN
console.log( a * arr_a )//0
console.log( a * arr_b )//NaN

​ 上边的例子中所有对象的隐式类型转化都是先调用了toString()方法,再调用了Number()方法,最终把对象转化为了数字,最后再参与运算。

​ 所有数据类型的除法和乘法的道理是一样的,简单类型都直接通过Number()函数转:

var a = '2',
    b = '2'
console.log( a / b )//1 ,字符串被转化为了数字

var a = 1,
    b
console.log( a / b )//NaN
var c = '1',
    d
console.log( c / d )//NaN,Number()把字符串转化为了数字1,把undefined转化为了NaN
var e = 'hello',
    d 
console.log( e / d )//NaN,Number()把两个都转化为了NaN

var a = '4',
    b = 2
console.log( a / b )//2

var a = null,
    b = 2
console.log( a / b )//0,Number()把null转化为了0

var a = true,
    b = 2
console.log( a / b )//0.5,Number()把true转化为了1
var c = false,
    d = 2
console.log( c / d )//0,Number()把false转化为了0

​ 复杂数据类型,先调用toString()再调用Number():

var arr_a [],
    arr_b = [1,2,3],
    a = 2
console.log( arr_a / a )//0
console.log( arr_b / a )//NaN

var obj_a = {},
    obj_b = {name: 'xiaoming', age: 18},
    a = 2
console.log( obj_a / a )//NaN
console.log( obj_b / a )//NaN

总结

纯数字的运算和数学中的一样。

String -> 字符串

Array -> 数组

Object -> json形式的对象

Number -> 数字

加法:

只要不是数字 + 数字,所有的都被转化为了字符串,然后进行拼接

减法,除法,乘法:

只要不是数字 - 数字,所有都被转化为数字然后进行运算

js运算顺序

JavaScript运算符执行顺序:

1.()
2.!,–,++,正号,负号
3.*,/
4.+,-
5.<,>,>=,<=
6.,!=,=,!==
7.&&
8.||
9.?:
10.=,+=,-,-=,*=,/=,%=(赋值运算)

小建议,任何时候只要不确定运算顺序就加括号。

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐