第十五节:各种逻辑运算符总结(&&、||、?、??、&&=、||=、??=)

一. 各种运算符

1 . && 逻辑与

 含义:形如 x && y, x为ture的时候,返回y 或者 执行y (y可能是表达式,也可能是函数),否则返回 x 。

 PS:除了 0、空字符串" "、NaN、false、null、undefined以外,都为 ture 。

{
    console.log("----------------1.&& 逻辑与-------------------");
    // 之前的写法
    let msg1 = "ypf";
    let msg2 = 0;
    let msg3 = "";
    msg1 = msg1 && "default value";
    msg2 = msg2 && "default value";
    msg3 = msg3 && "default value";
    console.log(msg1); //ypf
    console.log(msg2); //0
    console.log(msg3); //空字符串""
}

 

2. || 逻辑或

 含义:形如 x || y, 左侧x为false时返回y 或者 执行y (y可能是表达式,也可能是函数),否则返回x。

 注意:如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。 比如 ' '、0、NaN、false,都认为是flase,不符合实际情况,是有bug的。(null 和 undefined认为是false是正常的)

{
    console.log("---------------- 2. || 逻辑或-------------------");
    // 先看一下||的弊端吧, 下面4种情况,都想原样输出,而不是输出默认值
    console.log("" || "default value"); //default value
    console.log(0 || "default value"); //default value
    console.log(NaN || "default value"); //default value
    console.log(false || "default value"); //default value

    let msg1 = "ypf";
    let msg2 = 0;
    let msg3 = "";
    msg1 = msg1 || "default value";
    msg2 = msg2 || "default value";
    msg3 = msg3 || "default value";
    console.log(msg1); //ypf
    console.log(msg2); //default value  【0的bug】
    console.log(msg3); //default value  【空“”的bug】
}

 

3. 可选链 ? 【ES11-ES2020】

(1). 背景:

        多层级的对象时,调用内层的属性或方法,需要加前置校验,判断是否存在,否则会导致程序报错,中断,无法执行下面的业务。

(2). 可选链的符号:?

(3). 可选链的用法:可选链中的 ? 表示【如果问号左边表达式有值, 就会继续查询问号后面的字段, 如果没有值,不会报错,返回undefined】

      A. 对象中使用:调用属性和方法

      PS:对于方法而言,注意一下下面的两种写法的含义的区别

       console.log(userInfo?.myChild2?.getMsg()); //undefined  (表示当userInfo存在且myChild2存在的时候调用getMsg())

       console.log(userInfo?.myChild2?.getMsg?.()); //undefined (和上边有区别,这里表示当userInfo存在且myChild2存在且getMsg存在的时候才调用)

      B. 数组中使用

      C. 与空值运算符一起使用

注意:可选链不能用于赋值!!!!!!!

{
    console.log(
        "---------------- 3. 可选链 ? 【ES11-ES2020】-------------------"
    );
    const userInfo = {
        name: "ypf",
        age: 18,
        getMsg() {
            return "hello world";
        },
        myChild: {
            cName: "lmr",
            cAge: 10,
            getMsg() {
                return "hello ypf";
            },
        },
    };

    // 一. 之前写法
    //1. 想获取myChild中的cAge属性和getMsg方法,需要这么写
    const cAge = userInfo && userInfo.myChild && userInfo.myChild.cAge;
    const cMsg = userInfo && userInfo.myChild && userInfo.myChild.getMsg();
    console.log(cAge);
    console.log(cMsg);

    //2. 想获取myChild2中的cHeight属性 和 getMsg()方法【实际上并没有myChild2】
    //下面这种写法直接报错,并且会导致后续的代码不能运行
    // TypeError: Cannot read properties of undefined (reading 'cHeight')
    /*     {
        const cHeight = userInfo.myChild2.cHeight;
        console.log(cHeight);
    } */

    // 所以我们就得这样写:获取的是cHeight,我们就需要判断到它的上一级是否存在,即myChild2
    // 结果:由于myChild2不存在, 所以无法进if内部,所以不影响后续代码
    if (userInfo && userInfo.myChild2) {
        console.log(userInfo.myChild2.cHeight);
    }
    if (userInfo && userInfo.myChild2) {
        userInfo.myChild2.getMsg();
    }
    // 当然我们也可以这样写
    // 结果:输出都是undefined,但不影响后续运行
    console.log(userInfo && userInfo.myChild2 && userInfo.myChild2.cHeight);
    console.log(userInfo && userInfo.myChild2 && userInfo.myChild2.getMsg());

    // 二. ES11中的写法
    console.log("------------------ES11中的写法-----------------------------");
    //1. 想获取myChild中的cAge属性和getMsg方法,需要这么写  【对象中存在】
    console.log(userInfo?.myChild?.cAge); //10
    console.log(userInfo?.myChild?.getMsg()); //hello ypf

    //2. 想获取myChild2中的cHeight属性 和 getMsg()方法【实际上并没有myChild2】
    console.log(userInfo?.myChild2?.cHeight); //undefined (表示当userInfo存在且myChild2存在的时候调用cHeight)
    console.log(userInfo?.myChild2?.getMsg()); //undefined  (表示当userInfo存在且myChild2存在的时候调用getMsg())
    console.log(userInfo?.myChild2?.getMsg?.()); //undefined (和上边有区别,这里表示当userInfo存在且myChild2存在且getMsg存在的时候才调用)

    // 3. 数组中使用
    // 数组中使用(不常见,因为直接arr[42]也是undefined)
    let arr = [1, 2, 3];
    console.log(arr[42]); // undefined
    console.log(arr?.[42]); // undefined

    // 4. 与空值运算符??一起使用
    let customer = {
        name: "ypf",
    };
    console.log(customer?.city ?? "青岛"); // "青岛"

    // 5. 可选链不能用于赋值
    // {
    //      let obj1 = {};
    //  obj1?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
    // }

    console.log("--------------执行完毕----------------");
}

 

4. 空值合并运算符?? 【ES11-ES2020】

(1) 背景:

        解决了之前逻辑或操作符(||)的几个弊端:

        ||的含义:左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。

        比如为假值(例如'',0,NaN,false)时

(2). 符号: ??

(3). 用法:当左侧的操作数为 null或者undefined时,返回其右侧操作数,否则返回左侧操作数。

{
    console.log("----------------4. 空值运算符【符号:?】-----------------");
    // 先看一下||的弊端吧, 下面4种情况,都想原样输出,而不是输出默认值
    console.log("" || "default value"); //default value
    console.log(0 || "default value"); //default value
    console.log(NaN || "default value"); //default value
    console.log(false || "default value"); //default value

    // 同样上面的情况,再来看一下空值运算符?? 都是原样输出了,达到目的了
    console.log("" ?? "default value"); //空字符串""
    console.log(0 ?? "default value"); //0
    console.log(NaN ?? "default value"); //NaN
    console.log(false ?? "default value"); //false

    // 针对null 和 undefined, || 的结果,走的都是默认值,达到目的了
    console.log(null || "default value"); //default value
    console.log(undefined || "default value"); //default value

    // 针对null 和 undefined, ?? 的结果,走的都是默认值,达到目的了
    console.log(null ?? "default value"); //default value
    console.log(undefined ?? "default value"); //default value

    // 除了null和undefined外,??的结果都是本身
    console.log(1 ?? "default value"); //1
    console.log("msg" ?? "default value"); //"msg"
    console.log(["ypf1", "ypf2"] ?? "default value"); //["ypf1", "ypf2"]
}

 

5. ||=  逻辑或赋值运算 【ES12-ES2021】

     含义: 形如 x ||= y 运算仅在 x 为false时,返回右侧的值y,否则仍然返回值x, 实际上可以认为它是 x||(x=y) 的缩写,所以 ||= 也存在一下意外的bug,比如:0、“”、NaN、false,都认为是false,都会执行 ||= 右侧的代码

     PS:针对null 和 undefined,执行右侧代码这是我们所需要的,是正确的。

{
    console.log("----------------5. ||=  逻辑或赋值运算-------------------");
    let msg1 = "ypf";
    let msg2 = 0;
    let msg3 = "";
    msg1 = msg1 || "default value";
    msg2 = msg2 || "default value";
    msg3 = msg3 || "default value";
    console.log(msg1); //ypf
    console.log(msg2); //default value  【0的bug】
    console.log(msg3); //default value  【空“”的bug】

    // 上述写法等价于
    let msg11 = "ypf";
    let msg22 = 0;
    let msg33 = "";
    msg11 ||= "default value";
    msg22 ||= "default value";
    msg33 ||= "default value";
    console.log(msg11); //ypf
    console.log(msg22); //default value  【0的bug】
    console.log(msg33); //default value  【空“”的bug】
}

6. &&=  逻辑与赋值运算  【ES12-ES2021】

    含义:形如 x &&= y 运算仅在 x 为ture时,返回右侧的值y,否则仍然返回值x, 实际上可以认为它是 x && (x=y) 的缩写

    PS:除了 0、“”、NaN、false、null、undefined以外,都为ture

{
    console.log("----------------6. &&=  逻辑与赋值运算-------------------");
    // 之前的写法
    let msg1 = "ypf";
    let msg2 = 0;
    let msg3 = "";
    msg1 = msg1 && "default value";
    msg2 = msg2 && "default value";
    msg3 = msg3 && "default value";
    console.log(msg1); //ypf
    console.log(msg2); //0
    console.log(msg3); //空字符串""

    // 上述写法等价于
    let msg11 = "ypf";
    let msg22 = 0;
    let msg33 = "";
    msg11 &&= "default value";
    msg22 &&= "default value";
    msg33 &&= "default value";
    console.log(msg11); //ypf
    console.log(msg22); //0
    console.log(msg33); //空字符串""
}

 

 7. ??=  逻辑空赋值运算符  【ES12-ES2021】

     含义:形如 x ??= y 运算仅在 x 为null或undefined时,返回右侧的值y,否则仍然返回值x, 实际上可以认为它是 x ?? (x=y) 的缩写

{
    console.log("----------------7. ??=  逻辑空赋值运算-------------------");
    // 之前的写法
    let msg1 = "ypf";
    let msg2 = 0;
    let msg3 = "";
    let msg4 = null;
    let msg5 = undefined;
    msg1 = msg1 ?? "default value";
    msg2 = msg2 ?? "default value";
    msg3 = msg3 ?? "default value";
    msg4 = msg4 ?? "default value";
    msg5 = msg5 ?? "default value";
    console.log(msg1); //ypf
    console.log(msg2); //0
    console.log(msg3); //空字符串""
    console.log(msg4); //"default value";
    console.log(msg5); //"default value";

    // 上述写法等价于
    let msg11 = "ypf";
    let msg22 = 0;
    let msg33 = "";
    let msg44 = null;
    let msg55 = undefined;
    msg11 ??= "default value";
    msg22 ??= "default value";
    msg33 ??= "default value";
    msg44 ??= "default value";
    msg55 ??= "default value";
    console.log(msg11); //ypf
    console.log(msg22); //0
    console.log(msg33); //空字符串""
    console.log(msg44); //"default value";
    console.log(msg55); //"default value";
}

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2022-03-24 11:49  Yaopengfei  阅读(1458)  评论(1编辑  收藏  举报