美文网首页JavaScript
JavaScript快速入门-04-运算符

JavaScript快速入门-04-运算符

作者: Surpassme | 来源:发表于2022-08-22 00:08 被阅读0次

    4 运算符

    4.1 算术运算符

    4.1.1 概述

        JavaScript 提供的算术运算符如下所示:

    类型 符号 示例
    加法运算符 + a+b
    减法运算符 - a-b
    乘法运算符 * a*b
    除法运算符 / a/b
    余数运算符 % a%b
    自增运算符 ++ ++a/a++
    自减运算符 -- --a/a--
    指数运算符 ** a**b

    4.1.2 加法运算符

        加法运算符是最常见的运算符,常用于求两个数值的和。

    4.1.2.1 基本规则

    • 1.数值相加

        如果是进行数值的相加,则为求和

    1+2 // 3
    
    • 2.布尔类型相加
          在JavaScript中,也允许非数值相加,例如与布尔类型的相加。

    在与布尔类型相加时,则会自动将布尔类型转换为数值,然后再进行相加。true会转换为1,false会转换为0

    true+true // 2
    3+true // 4
    false+false  // 0
    
    • 3.字符串相加

        如果是与字符串类型的值相加,则会进行字符串的连接,并返回一个新的字符串。如果其中一个不是字符串,则会自动转换为字符串再进行连接。

    "I Love"+" Surpass"  // 'I Love Surpass'
    2+"-28" // '2-28'
    true+" boolean" // 'true boolean'
    

        加法运算符是在运行时决定,到底是执行相加,还是执行连接,即运算子不同,执行不同的语法行为,也称之为重载。因加法运算符存在重载行为,可能执行不同的运算,使用的时候需要特别注意。

    "2020"+4+3 // '202043'
    2020+4+"3" // '20243'
    

    上面代码中,因为是从左到右进行运算,字符串的位置不一样,则会出现不一样的结果

        除了加法运算符,其他算术运算符(如减法、除法、乘法、余数等)则不会发生重载。其规则:所有运算子一律先转换为数值,再进行相应的算术运算

    100-"88" // 12
    100*"88" // 8800
    100/"88" // 1.1363636363636365
    100%"88" // 12
    

    4.1.2.2 对象相加

        如果运算子是对象,必须先转换为原始类型的值,再进行相加

    var obj={name:"surpass"};
    console.log(obj+8) // [object Object]8
    

    上面代码中,对象obj转换成原始类型的值是[object Object],再与8相加就得到结果[object Object]8

        对象转换成原始类型的值,规则如下所示

    • 1.首先自动调用对象的valueOf()方法,再调用对象的toString()方法
    var obj={name:"surpass"};
    console.log(obj.valueOf()); // { name: 'surpass' }
    console.log(obj.valueOf().toString()); // [object Object]
    

    一般来说,对象的valueOf()方法总是返回对象自身,再调用对象的toString()方法,将其转换为字符串。在知道这个规则后,我们可自定义valueOf()和toString()方法,得到想到的结果。

    var obj = { 
        valueOf: function () {
             return 28; 
            } 
        };
    console.log(obj + 8); // 36
    

    上述代码由于直接定义了obj的valueOf()方法返回28,再与8相加得到结果36。由于valueOf()方法直接返回一个原始类型的值,所以不再调用toString()方法。我们也可以自定义toString()方法,如下所示:

    var obj = { 
        toString: function () {
             return "Surpass "; 
            } 
        };
    console.log(obj + 8); // Surpass 8
    

        但这里有一个特例,如果运算子是一个Date的对象实例,则优先执行toString()方法,如下所示:

    var obj=new Date();
    obj.valueOf=function(){return 28;};
    obj.toString=function(){return "Surpass "};
    console.log(obj+100);  // Surpass 100
    

    4.1.3 余数运算符

        余数运算符主要用于计算两个数的余数。

    15%5 // 0
    15%7 // 1
    

        需要注意的是,运算结果的正负号是由第一个运算子的正负号决定。

    -15%5 // -0
    -15%7 // -1
    

    4.1.4 自增/自减运算符

        自增和自减运算符,是一元运算符,只需要一个运算子。其作用是将运算子首先转换为数值,然后再加1或减1,会修改原始变量。

    var a=100;
    var b=88;
    var c=99;
    var d=66;
    console.log("a++ value is:",a++);
    console.log("a value is:",a);
    console.log("b value is:",b);
    console.log("++b value is:",++b);
    console.log("c-- value is:",c--);
    console.log("c value is:",c);
    console.log("d value is:",d);
    console.log("--d value is:",--d);
    

    输出结果如下所示:

    a++ value is: 100
    a value is: 101
    b value is: 88
    ++b value is: 89
    c-- value is: 99
    c value is: 98
    d value is: 66
    --d value is: 65
    

        通过以下结果,可以总结出以下结论

    • 自增和自减运算符在变量前面,先进行自增或自减操作后,再输出其值
    • 自增或自减运算符在变量之后,先输出其值,再进行自增或自减操作

    4.1.4 指数运算符

        指数运算符通常用于一个数的n次幂。

    2**5 // 32
    

        这里有一个注意事项,指数运算符是右结合,而不是左结合,即多个指数运算符连用时,先进行最右边的计算

    2**3**2  // 512
    2**4**2**1 // 65536
    

    4.2 比较运算符

    4.2.1 概述

        比较运算符一般常用于比较两个值的大小,然后返回一个布尔值,用于表示是否满足条件。JavaScript 提供的比较运算符如下所示:

    类型 符号 示例
    大于运算符 > a>b
    大于等于运算符 >= a>=b
    小于运算符 < a<b
    小于等于运算符 <= a<=b
    相等运算符 == a==b
    严格相等运算符 === a===b
    不相等运算符 != a!=b
    严格不相等运算符 !== a!==b

        以上比较运算符可以分为相等比较运算符不相等运算符。两者的比较的规则是不一样的。对于不相等的比较规则为两个运算子都为字符串,按照字典顺序比较(实际上是比较Unicode码点),如果不是,则转换为数值,再比较数值大小

    4.2.2 不相等运算符

    4.2.2.1 字符串比较

        在JavaScript中比较字符串时,会首先比较首字符的Unicode码点。如果相等,再比较第二个字符的Unicode码点,以此类推。

    "Surpass" < "surpass" // true
    

        上面代码中s的码点(115)大于S的码点(83),所以返回true,因为汉字也有Unicode码点,所以汉字也可以进行比较的,如下所示:

    "上" > "海" // false
    

    上面代码中,上的码点为:19978,海的码点为:28023,所以返回为false

    4.2.2.2 非字符串比较

        因为参与比较的运算子一般都有2个,则可以分为两种情况:

    1.原始类型值

        如果两个运算子都是原始类型值,则先转换为数值再进行比较。如下所示:

    5 > "4" // true,会先将"4"转换为数值4,再参与比较
    true > false // true ,会将true和false转换为数值,分别对应为1和0,再参与比较
    5 > false // true
    

        这里有一个特殊情况,就是与NaN进行比较,任何值与NaN使用不相等运算符比较,均返回false

    1 > NaN // false
    "abc" >= NaN // false
    NaN == NaN // false
    

    2.对象

        如果运算子是对象,则会转换为原始类型值,再进行比较。

    对象转换为原始类型值,则先调用对象的valueOf()方法;如果返回值仍然为对象,则再调用toString()方法

    var number=10;
    var testArray=[8];
    console.log("testArray toString value is:",testArray.valueOf().toString()); // testArray toString value is: 8
    console.log("testArray > number",testArray>number); // testArray > number false
    
    var objA={"name":"Surpass"};
    var objB={"age":28};
    console.log("objA >= objB",objA >= objB); // objA >= objB true 
    

    4.2.3 严格比较运算符

        严格比较运算符包括严格相等运算符严格不相等运算符

    4.2.3.1 严格相等运算符

        在JavaScript中提供两种相等运算符=====,两者主要区别如下所示:

    • ==是比较两个值是否相等,即两边类型允许不一致
    • ===是比较两个值是否为同一个值,即要求两边类型必须一致,否则则返回false

    1.不同类型值

    1=="1" // true
    1==="1" // false
    true == 1 // true
    true === 1 // false
    

    2.同类型的原始类型值

    2==0x2  // true
    2===0x2 // true
    

    NaN与任何值都不相等

    NaN == NaN   // false
    NaN === NaN  // false
    

    3.复合类型

        两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个内存地址

    let objA={};
    let objB={};
    let objC=objA;
    console.log("objA === objB ?",objA === objB);
    console.log("objA === objC ?",objA === objC);
    
    let funA=function(){};
    let funB=function(){};
    let funC=funA;
    console.log("funA === funB ?",funA === funB);
    console.log("funA === funC ?",funA === funC);
    

    输出结果如下所示:

    objA === objB ? false
    objA === objC ? true
    funA === funB ? false
    funA === funC ? true
    

    对于两个对象的比较,严格相等运算比较的是其内存地址,而大于或小于运算符比较的是值

    4.undefined和null

        undefined和null与自身严格相等

    undefined === undefined // true
    null === null // true
    

    4.2.3.2 严格不相等运算符

        严格不相等运算符与严格相等运算符类似,主要用于判断两个是否严格不相等。

    1 !== "1" // true
    

    4.2.4 相等运算符

        相等运算符常用于比较两个运算子是否相等,通常分为以下几种情况:

    • 如果是相同类型的数据进行比较时,则等同于严格相等运算符
    • 如果是不同类型的数据时,则会先将两边数据进行转换,再使用严格相等运算符进行比较

    4.2.4.1 原始类型值

        原始类型值会先转换成数值再进行比较,如下所示:

    1 == true // true
    2 == false // false
    "true" == true // false 等同于Number("true")  = NaN
    "" == false // true 等同于Number("") = 0
    

    4.2.4.2 对象与原始类型值

        对象与原始类型值比较时,对象在转换为原始类型值再参与比较,即先调用对象的valueOf()方法,再调用toString()方法后,再参与比较。

    [1] == 1  // true
    [1,2,3] == "1,2,3" // true
    [1] == true // true
    

        以上代码中,如果是对象参与相等判断时,JavaScript会调用对象的valueOf()方法,由于返回的还是一个对象,则会再调用toString()方法,得到字符串后,再基于规则进行比较,我们来看一个比较直观的例子,如下所示:

    var obj={
        valueOf:function(){
            console.log("call valueOf method");
            return obj;
        },
        toString:function(){
            console.log("call toString method");
            return "Surpass";
        }
    };
    var myName="Surpass";
    console.log("myName == obj result is: ", myName == obj);
    

    输出结果如下所示:

    call valueOf method
    call toString method
    myName == obj result is:  true
    

    4.2.4.3 undefined 和 null

        undefined和null只有与自身比较,或者相互比较时,才会返回true;与其他类型的值比较时,结果都为false,如下所示:

    // 与自身或相互比较
    undefined == undefined // true
    null == null // true
    undefined == null // true
    // 与其他类型比较
    false == null // false
    false == undefined  // false
    2 == null // false
    2 == undefined // false
    

    4.3 布尔运算符

    4.3.1 概述

        布尔运算符一般用于将表达式值转换为布尔值,主要包括以下几种:

    • 与运算符:&&
    • 或运算符:||
    • 非运算符:!

    4.3.2 与运算符

        &&运算符常用于多个表达式的求值。其运算规则如下所示:

    • 所有表达式的值均为true时,返回true
    • 如果第一个表达式值为false时,则直接返回false
    • 如果第一个运算子的布尔值为true,则返回第二运算子的值(注意这里不是布尔值),如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值
    true && true // true
    true && 3>2 && false // false
    "t" && "f" // f
    "" && "Surpass" // ""
    

        与运算符还是一种短路运算符,即如果第一个运算子决定了结果,则不会对后续运算子进行操作求值。示例如下所示:

    var found=false;
    var result=(found && age); // 不会报错,因为第一个运算子是false
    console.log("result is: ",result); // 执行打印
    
    var found=true;
    var result=(found && age); // 会报错,因为age没有事先声明
    console.log("result is:",result); // 不会执行
    

        利用这个短路特性,可以取代if结构,如下所示:

    function doSomething(){
        console.log("call doSomething method");
    }
    
    var flag=true;
    if (flag){
        console.log("call if");
        doSomething();
    }
    
    flag && doSomething(); //利用短路特性
    

    输出结果如下所示:

    call if
    call doSomething method
    call doSomething method
    

        对于特殊字符的处理逻辑如下所示:

    • 如果有一个运算子是null,返回null
    • 如果有一个运算子是NaN,返回NaN
    • 如果有一个运算子是undefined,返回undefined

    4.3.3 或运算符

        || 也可以用于多个表达式求值。,其运算规则如下所示:

    • 所有表达式中,只有一个表达式值为true,则为true
    • 如果第一个表达式为true,则直接返回true
    • 如果第一个运算子的布尔值为true,则返回第一个运算子的值,且不再对第二个运算子求值,如果第一个运算子的布尔值为false,则返回第二个运算子的值
    "true" || "true" //  true
    true || 3 > 2 && false  //  true
    "t" || "f" // t
    "" || "Surpass"
    "true" || 2>3 || false  // true
    

    短路规则同样也适用于或运算符

        对于特殊字符的处理逻辑如下所示:

    • 如果两个运算子都是null,返回null
    • 如果两个运算子都是NaN,返回NaN
    • 如果两个运算子都是undefined,返回undefined

    4.3.4 非运算符

        非运算符常用于将一个布尔值变为其反值,即true变为false,false变为true。

    !true // false
    !false // true
    

        对于非布尔值,非运算符会将其转换为布尔值,以下6个值进行非运算后为true,其他值均为false

    • undefined
    • null
    • false
    • 0
    • NaN
    • 空字符串("")

    4.4 其他运算符

    4.4.1 逗号运算符

        逗号运算符可以用来在一条语句中执行多个操作,如下所示:

    let a=1,b=2,c=3;
    console.log("a value is;"+a+"\nb value is:"+b+"\nc value is:"+c);
    

    输出结果如下所示:

    a value is;1
    b value is:2
    c value is:3
    

    4.4.2 条件运算符

        条件运算符语法格式如下所示:

    variable = boolean_expression ? true_value : false_value;
    

        variable最终值取决于boolean_expression的值,如果boolean_expression为true,则赋值true_value,否则,则赋值false_value,示例如下所示:

    let a=100,b=123;
    let result=(a>b)?"a大于b":"a小于b";
    console.log("result is:",result) // result is: a小于b
    

    相关文章

      网友评论

        本文标题:JavaScript快速入门-04-运算符

        本文链接:https://www.haomeiwen.com/subject/ivwbgrtx.html