0%

算术运算符 & 比较运算符 & 比较运算符

算术运算符

在算术运算符中,+ 号有两种意义:

  • 数字加法;

  • 字符串拼接;

    在本节当中所讲知识点主要偏向实验性的,可以参考一下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var iNum=3+3;
    document.write('[+] iNum=' + iNum + '<br>');

    iNum=iNum+3;
    document.write('[+] iNum=' + iNum + '<br>');

    iNum=Number.MAX_VALUE+1E307;// number 表示的最大值
    document.write('[+] iNum=' + iNum + '<br>');
    iNum=iNum+1E307;
    document.write('[+] iNum=' + iNum + '<br>');

    运行结果为:

    1
    2
    3
    4
    [+] iNum=6
    [+] iNum=9
    [+] iNum=Infinity
    [+] iNum=Infinity

    知识扩展:Infinity

    在 Js 中,Infinity 指的是任何超过浮点数上限(1.7976931348623157E+10308)的值,对于-Infinity则是指超过浮点数下限(-1.7976931348623157E+10308)的值。Infinity 的类型为 number 。当怀疑某个值过大时,可以检查它是否为 Infinity ;特殊的是,将 Infinity 与它自己相减时,结果为 NaN。

    NaN:

    首先需要注意大小写,Js 中定义的是 NaN,而不是 NAN

    1. Js 中使用 NaN(通常被称为非数字,Not a Number)来表示它无法表示的数值结果,如0/0
    2. NaN 是 Js中唯一一个与自身不相等的值,即 NaN != NaN。实际上,NaN 与任何东西(包括它自身)都不相等,因此在检查时,不能通过if(xx == NaN)这种方式判断,而需要使用特殊函数 isNaN(当值为NaN 时,返回 true)
    3. NaN的类型是 number,所以与其把 NaN 叫做“不是数字”,还不如称之为“无法表示的数字”。

    关于 NaN ,可以看下面代码:

    1
    2
    iNum = Number.Infinity + 1;//返回值为 NaN ,记下就行
    document.write('[+] iNum=' + iNum + '<br>');

    返回结果:

    1
    [+] iNum=NaN

    这是一道面试中经常会被问到的问题,对于这个问题只能记下。

    下面让我们一起来学习 + 号字符串的拼接:

    1
    2
    3
    4
    5
    6
    7
    var sToken='abc' + 'edf';
    document.write('[+] sToken =' + sToken + '<br>');

    var sToken ='5' + 5;//返回值是 55 ,这边做了隐形的类型转换
    document.write('[+] sToken =' + sToken + '<br>');
    var sToken = 5 + '5';//将数字转化为字符串
    document.write('[+] sToken =' + sToken + '<br>');

    运行结果:

    1
    2
    3
    [+] sToken =abcedf
    [+] sToken =55
    [+] sToken =55

    对于第一个结果大家大部分可以理解,为什么第二个跟第三个结果是这样子的呢?在+ 号字符串拼接中,计算机做了隐性的类型转换,将数字转化为字符串。那么,我们再来看以下这个代码,

    1
    2
    var sToken ='5' - 5;
    document.write('[+] sToken =' + sToken + '<br>');

    大家最开始想到的返回值是多少呢,学过 C 语言以及 c++ 的同学可能会感到很疑惑,代码可以这样写吗?这段代码是可以运行的,结果是:

    1
    [+] sToken =0

    计算机将前面的字符串转化为数字,-号只有数字减法,所以最终结果为0。

    下面我们来学习 ++ 运算符:++ 在 Js 中已经无较大必要了 ,它 等价于 iNum =iNum+1。有两种表现形式,一个是先自加后执行运算,另一个是先执行后自加。可以通过以下几个代码理解:

    1. 先自加后执行运算
    1
    2
    iNum=5;
    document.write('[++] iNum=' + ++iNum + '<br>');

    结果是 6 ,其实对于这种代码写法只是为了方便学习者学习,在以后工作中这种代码写法是万万不可行的,一般标准写法如下:

    1
    2
    3
    iNum=5;
    ++iNum;
    document.write('[++] iNum=' + iNum + '<br>');

    这种写法的执行结果也是 6 ,但整体给人的感觉就较为规范整齐,也是公司老板愿意看到的结果。

    2.先执行运算后自加

    1
    2
    iNum=5;
    document.write('[++] iNum=' + iNum++ + '<br>');

    上面结果的执行结果是 5 。

    下面我们把这两者结合在一起运算,例如:

    1
    2
    3
    iNum=7;
    iNum=10 — ++iNum + ++iNum - iNum++ - iNum++;
    document.write('[++] iNum=' + iNum + '<br>');

    上面代码的运算结果是 -8。

    主要的运算思路是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    iNum:7 
    iNum=10 — ++iNum + ++iNum - iNum++ - iNum++ iNum:8
    iNum=108 + ++iNum - iNum++ - iNum++
    iNum=2 + ++iNum - iNum++ - iNum++ iNum:9
    iNum=2 + 9- iNum++ - iNum++ iNum:9
    iNum=11 - iNum++ - iNum++ iNum:9
    iNum=11 - 9 - iNum++ iNum=10
    iNum=2 - 10
    iNum=-8
    8

    在这边呢,建议大家在做这种较为复杂的运算题时,采用这种逐步计算的方法,避免错误。

    比较运算符

    我们今天主要继昨天算术运算符的学习来进一步学习比较运算符,比较运算符是将两串字符串的头一个字母进行比较,若第一个字母都相同,则继续将第二个字母进行比较,循序渐进。下面通过一段代码来理解:

    1
    2
    3
    document.write('[>] \'aaa\' > \'bbb\' ?' + ('aaa' > 'bbb') + '<br>');
    document.write('[>] \'aaa\' > \'abb\' ?' + ('aaa' > 'abb') + '<br>');
    document.write('[>] \'aaa\' > \'aBb\' ?' + ('aaa' > 'aBb') + '<br>');

    上述代码的运行结果为:

    1
    2
    3
    [>] 'aaa' > 'bbb' ?false
    [>] 'aaa' > 'abb' ?false
    [>] 'aaa' > 'aBb' ?true

    相信通过代码示例,大家可以更好的学习本讲知识,主要是 ASCII 码的比较。

    常见ASCII码的大小规则:09<AZ<a~z。

    1)数字比字母要小。如 “7”<“F”;

    2)数字0比数字9要小,并按0到9顺序递增。如 “3”<“8” ;

    3)字母 A 比字母 Z 要小,并按 A 到 Z 顺序递增。如“A”<“Z” ;

    4)同个字母的大写字母比小写字母要小32。如“A”<“a” 。

    几个常见字母的 ASCII 码大小: “A” 为65;“a”为97;“0”为 48 ,65~90为26个大写英文字母,97~122号为26个小写英文字母。

    下面我们来看个更深层次的比较:

    1
    document.write('[<] \'25\' < \'4\' ?' + ('25' < '4') + '<br>');

    这个运算结果是 true ,这个主要就是 2 和 4 在比较,还是比较容易理解的,那么,有个更值得思考的东西来了,

    1
    document.write('[<] \'25\' < 4 ?' + ('25' < 4) + '<br>');

    这个会报错吗?字符串可以直接跟数字进行比较吗?可以肯定的告诉你,这个是不会报错的,并且运行结果是 false 。相信看到这个运算结果大家已经知道为什么了,是的,在这里,电脑将字符串 ‘ 25 ’ 转化为数字 25 ,然后去与 4 进行比较,得到结果是错误的。这就有点类似上节的字符串拼接那块的 -号,只要有一个字符串和一个数字进行运算,那么都会将字符串强制转换为数字去运算,在这里,需要大家将这个记忆下来,没有规则可言。

    下面学习三目运算符,三目运算符,又称条件运算符。它是唯一有3个操作数的运算符,有时又称为三元运算符。对于条件表达式 b ? x : y,先计算条件b,然后进行判断。如果 b 的值为 true,计算 x 的值,运算结果为 x 的值;否则,计算 y 的值,运算结果为 y 的值。一个条件表达式绝不会既计算 x,又计算 y。条件运算符是右结合的,也就是说,从右向左分组计算。例如,a ? b : c ? d : e 将按 a ? b : (c ? d : e) 执行。

    1
    document.write('[?:] 25>4?' + (25>4 ? 'l' : 's') + '<br>');

    结果为:

    1
    [?:] 25>4?l

    如果大家理解了三目运算符的定义,这个是比较容易理解的。25 和 4 比较,结果是真,所以运算结果为 l ,否则为 s 。

    对于 == ,主要通过以下代码了解以下即可:

    1
    2
    document.write('[==] null == undefined ?' + (null == undefined) + '<br>');   //   true
    document.write('[==] \'NaN\' == NaN ?' + ('NaN' == NaN) + '<br>'); // false

    运行结果附在语句后面,这个其实在前面所讲的知识中就有涉及到,所以比较容易理解,就不深入讲解了。

    接下来,我们看个工作中较为实用的例子:

    1
    2
    document.write('[==] false == 0 ?' + (false == 0) + '<br>');  // true
    document.write('[==] true == 1 ?' + (true == 1) + '<br>'); //true

    这两个运行结果都是 true ,跟 null == undefined 是一样的道理,都是一对的使用,就像一把钥匙开一把锁,在工作中是比较经常用到的。

    下面呢,看个具有挑战性的东西,

    1
    document.write('[==] null == 0 ?' + (null == 0) + '<br>');    //false

    对于一些 c++ 学的比较好的同学,可能会认为返回结果是 true ,但是,这边是返回 false ,这个是要知道的。

    规则:
    • 如果一个运算数是 Boolean 值,在检查相等性之前把它转换成数字值。false 转换为 0,true 为 1。
    • 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换为数字。
    • 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换为字符串。
    • 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换为数字。

    逻辑运算符

    今天接着学习逻辑运算符,所谓的逻辑运算符有: ! && ||。

    我们先来看 && ,当 && 连接语句时,两边的语句会转化为布尔类型(Boolean),然后再进行运算,具体的运算规则如下:

    1、两边条件都为 true 时,结果才为 true;

    2、如果有一个为 false,结果就为 false;

    1
    2
    3
    4
    document.write('[&&] true && false ?' + (true && false) + '<br>');
    document.write('[&&] true && true ?' + (true && true) + '<br>');
    document.write('[&&] false && false ?' + (false && false) + '<br>');
    document.write('[&&] false && true ?' + (false && true) + '<br>');

    运行结果是:

    1
    2
    3
    4
    [&&] true && false ?false
    [&&] true && true ?true
    [&&] false && false ?false
    [&&] false && true ?false

    把代码跟上面所说的两条运算规则结合在一起学习,就可以理解为什么会是最后这样的运算结果了。

    3、当第一个条件为 false 时,就不再判断后面的条件

    注意:当数值参与逻辑与运算时,结果为 true,那么会返回的会是第二个为真的值;如果结果为 false ,返回的会是第一个为假的值。

    在这里,要补充的一点是,0 , undefined , null , NaN , ‘’ 等都等价于 false ,以下我们来看这段代码:

    1
    2
    3
    4
    document.write('[&&] undefined && true ?' + (undefined && true) + '<br>');  //undefied
    document.write('[&&] null && true ?' + (null && true) + '<br>'); //null
    document.write('[&&] NaN && true ?' + (NaN && true) + '<br>'); //NaN

    结果我直接附在语句的后面,可以看到的是,第一个条件语句都为假,所以返回的值是第一个为假的值。

    接下来我们学习逻辑运算符 || ,||表示逻辑或,会尝试将符号左侧转换为Boolean对象,如果左侧为true则表达式结果为左侧值,如果为false,则表达式结果为右侧值。

    1
    2
    3
    4
    5
    document.write('[||] true || false ?' + (true || false) + '<br>');  //true
    document.write('[||] true || true ?' + (true || true) + '<br>'); //true
    document.write('[||] false || false ?' + (false || false) + '<br>'); //false
    document.write('[||] false || true ?' + (false || true) + '<br>'); //true

    大家可以结合代码学习,这块知识点还是比较容易好理解的。

    最后,来谈运算符 !,所谓的 !,通俗点理解就是非对即错,非错即对。

    1
    document.write('[!] !false ?' + (!false) + '<br>');   //true

    接下来继续学习运算符的优先级,如下表所示:

    我们可以通过底下这段代码来理解优先级的运用,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var iNum = 4;
    document.write('[1]' + (30<15?!true:true,iNum*4+5<3==25>24&&false||true) + '<br>');
    //30<15?!true:true,iNum*4+5<3==25>24&&false||true
    //false?!true:true,iNum*4+5<3==25>24&&false||true
    //false?false:true,iNum*4+5<3==25>24&&false||true
    //true,iNum*4+5<3==25>24&&false||true
    //iNum*4+5<3==25>24&&false||true
    //4*4+5<3==25>24&&false||true
    //21<3==25>24&&false||true
    //false==true&&false||true
    //false&&false||true
    //false||true
    //true

    注释掉的部分是解表达式的过程,对于逗号表达式,只显示最后一个逗号后面的值,前面的全抛掉。当然,建议大家先自己根据理解算一下结果,再去看解答过程。

    最后,给大家插个以后较会经常被问到的知识点,我们当初学习 c 语言的时候,对于变量替换通常的做法就是引入第三个变量,但是,面试的时候经常会有一些较为奇葩的问法,如果不借助第三个变量,要怎么实现变量替换呢?

    1
    2
    3
    4
    5
    6
    var iNum2 = 123;
    var iNum3 = 456;
    iNum2 += iNum3; //123 + 456
    iNum3 = iNum2 - iNum3; // 123
    iNum2 = iNum2 - iNum3; // 456

    这种做法希望大家可以会,免得在面试的时候因为这样一道题目而吃亏。

您的支持是对我最大的鼓励