逻辑运算符、||、&&、!、!!、??


章节目录
上一篇:《if else》
下一篇:《空值合并,??运算符》


算术运算符用于连接(计算)算术表达式,计算产生算术结果。理论上,逻辑运算符用于连接(计算)逻辑表达式,也就是条件表达式,返回Boolean类型的结果。

之所以说以上论述属于理论上,是因为,在JavaScript中,逻辑运算符可以参与任何类型的计算,而不仅仅是Boolean,同样的,产生的结果也是多种多样的。

可能一部分同学已经开始困惑了,一会行一会不行,到底闹哪样?别急,本文将详细论述JavaScript中逻辑运算符的运算原理,相信你在读完本文后,一定可以掌控雷电!

JavaScript中有四种逻辑运算符:&&(与)、||(或)、!(非)、??(空值合并运算符),??运算符下节再讲。

或运算符||

双竖线组成的||就是或运算符,在学术上,或运算符只能操作Boolean类型的表达式,如下:

let r = true || false; //true

或运算符左右两侧任意一个表达式的结果为true,那么整个或表达式的结果就是true,总共包括如下四种情况:

let r1 = true || true;      //true
let r2 = true || false;        //true
let r3 = false || true;        //true
let r4 = false || false;   //false

以上四种情况,只有当左右两侧表达式都是false的时候,||表达式才会返回false

或表达式更为常见的用法是结合if使用,用于判断给定的表达式是否有true存在,如下:

let val = prompt('请输入一个数字',0);
if (val % 2 == 0 || val % 3 == 0){alert(`${val}不是2的倍数就是3的倍数!`);
}else{alert(`${val}既不是2的倍数,又不是3的倍数。`);
}

以上使用方法都是传统的,符合常规的使用方法,比较容易理解和使用。

但是,在JavaScript中,为了增强逻辑运算符的计算能力,赋予了更强大的特性,下面就详细介绍JavaScript中的||运算规则。

寻找第一个真(true)值

语法:

let r = exp1 || exp2 || exp3 ||...;
alert(r);

或运算符的运算符规则:

  1. 从左往右计算表达式exp1exp2exp3、… ;
  2. 计算表达式exp后,将其转换为Boolean,如果是true,停止计算并返回exp表达式的值
  3. 如果所有的表达式都计算过后,没有true值,则返回最后一个表达式的计算结果

返回值的类型不会做转换,所以||可以返回任何类型的值。

参与或运算的表达式组成了一个表达式链,或运算符从中找到第一个真值并返回,否则返回最后一个值。

举个栗子:

let r1 = 1 || 0;//1
let r2 = 'str' || false;//'str'
let r3 = null || '' || 1; // 1
let r4 = null || undefined;// undefined
let r5 = null || NaN;//NaN

获取表达式列表中的第一个有意义值

例如,我们在高考报志愿的时候,有三个志愿,只有第一志愿没有录取,第二志愿才有机会,其次才是第三志愿,这个过程叫做滑档,也是找到第一个真值(录取志愿)的过程。

使用||表达以上滑档过程:

let first = "";
let secon = "";
let third = "北京大学";
alert(first || secon || third || "家里蹲");

以上代码展示了三个志愿依次录取的过程,如果三个志愿都没有录取(都为空、假),那么就会返回家里蹲

短路计算

我们可以利用||表达式返回第一个真值的特性,选择想执行的代码段。

例如:

true || alert('不会执行');
false || alert('执行');

这么做的好处是,如果我们在做测试,又不想反复注释代码,就可以使用短路特性,选择性的执行某些代码。

例如,以上代码只会执行第二行,如果我们希望执行第一行,只需要把第一行的true改为false就好了。

实际上,更为常用的测试代码是:

1 || alert('不会执行');
0 || alert('执行');

这种短路的用法,实际上可以用其他方法代替,例如if语句。
这么使用的最大好处是,代码简介,且显得高端!

与运算符&&

两个&组成的&&就是与运算符,只有当&&两侧的表达式结果都是true时,与运算符才会返回true

与运算符的四种使用情形如下:

let r1 = true && true;      //true
let r2 = true && false;        //false
let r3 = false && true;        //false
let r4 = false && false;   //false

if语句结合使用的案例:

let val = prompt("请输入一个数字", 0);
if(val > 0 && val < 100){alert(`${val}大于0小于100`);
}

&&运算符同样被JavaScript赋予了其他特性。

寻找第一个假值

||寻找第一个真值相反,&&可以找到多个表达式中的第一个假值,如下表达式:

let r = exp1 && exp2 && exp3 && ...;

&&表达式在运算时,执行过程如下:

  1. 从左到右计算表达式exp1exp2exp3
  2. 在计算被一个表达式exp后,将计算结果转为Boolean类型,如果结果是false,停止计算并返回表达式结果;
  3. 如果所有的表达式计算结果转型后,都是true,则返回最后一个表达式结果。

参与&&运算的表达式组成了一个表达式链,与运算符从中找到第一个假值并返回,否则返回最后一个值。

举个栗子:

let r1 = 1 && 0;//0
let r2 = 'str' && false;//false
let r3 = null && '' && 1; // null
let r4 = null && undefined;// null
let r5 = null && NaN;//null

不要试图简化if

因为&&||具有一定的路径选择能力,可以作为简化if语句的一种选择。

举个栗子:

let x = 9;
x > 0 && alert(`${x}大于0`);

以上代码的效果等价于:

let x = 9;
if(x > 0){alert(`${x}大于0`);
}

虽然这样看起来更加简短,但是if语义更加明显,可读。所以建议按照每种语法设计之初的用途使用,避免写出神鬼莫测的代码。

非运算符!

英文的感叹号!表示逻辑非运算符,也就是把一个布尔值取反。

语法:

let r = !val;

!运算符的执行逻辑:

  1. 将操作手转为Boolean类型;
  2. 返回Boolean值的相反值;

例如:

let r1 = !false;//true
let r2 = !1;//false
let r3 = !'';//true
let r4 = !NaN;//true
let r5 = !undefined;//true

两个!!

两个!!可以用于将一个非Boolean类型的数据布尔化,这种用法和+把非数字类型转为数字类型有异曲同工之妙!!

例如:

let r1 = !!'str';//true
let r2 = !!0;//false

!!的执行原理也非常简单,第一个!将变量布尔化并取反,第二个!将取反后的布尔值再取反,也就是原值的布尔化。

这就和类型转换章节的Boolean()方法效果相同:

let r1 = Boolean('str');//true
let r2 = Boolean(0);//false

运算优先级

&&运算符的优先级高于||a && b || c && d等价于(a && b) || (c && d),就像乘除优先级高于加减一样。
!运算符在三者中拥有最高的运算优先级。

课后作业

  1. 变量r的值?
let r = null || 996 || NaN;
  1. 以下代码的执行结果?
alert(alert('哈哈') || true || alert('吼吼'));

章节目录
上一篇:《if else》
下一篇:《空值合并,??运算符》


12.逻辑运算符与、或、非、双感叹号、双问号相关推荐

  1. Kotlin 3. Kotlin 特殊符号的用法:双感叹号!!,问号?,双冒号::

    一起来学Kotlin:概念:3. Kotlin 特殊符号的用法:双感叹号!!,问号?,双冒号:: 这里介绍 Kotlin 特殊符号的用法,包括:双感叹号!!,问号?,双冒号::. 文章目录 一起来学K ...

  2. freemarker中 感叹号、双感叹号、问号、双问号 的使用方法

    1.?? <!-- ??是判断对象是否为空(??是?exists的缩写) --> <#if object ??>${object}<#if>   如果object不 ...

  3. C语言中双感叹号的作用

    1.C语言中双感叹号的作用 (1)感叹号的作用:感叹号是逻辑运算符,表示逻辑非,也就是把真变成假,把假变成真: (2)在C语言中,0值表示假,非0值都是真,所以感叹号会把非0值变成0,而把0值变成1: ...

  4. 谨以此文,献给我的大学四年—双非本科到双一流985的成长之路

    谨以此文,献给我的大学四年-双非本科到双一流985的成长之路 天才白痴梦 谨以此文,献给我的大学四年-双非本科到双一流985的成长之路 大一时光 大二时光 大三时光(高光时刻) 大四时光 随感 我承认 ...

  5. Javascript中!!(两个感叹号,双感叹号)的含义

    使用Javascript时,有时会在变量前面加上两个感叹号,这样做表示什么含义呢?Javascript中,!表示运算符"非",如果变量不是布尔类型,会将变量自动转化为布尔类型,再取 ...

  6. javascript中双感叹号(!!)作用

    作为一个前端,在开发过程中经常会遇到!!(双感叹号),那么!!究竟有何含义,以下做详细说明,并罗列了js各数据类型使用后(不含symbol)输出结果(小白可以参照): javascript中'!'是& ...

  7. javaScript 双感叹号用法

    在偶尔看源码的过程中. 看到有些判断的用法是: var a; if(!!a){console.log('打印')} 为什么要用两个感叹号(❕)呢? 因为js 是弱类型,单纯用一个! 感叹号去转义可能会 ...

  8. 【JS】单感叹号 和 双感叹号 的用法

    文章目录 用法 示例 用法 双感叹号!!可以将一个值转换成对应的Boolean值, 第一个感叹号!是将其转化成取反后的Boolean类型的值 第二个感叹号!!是将取反后的Boolean类型的值再进行一 ...

  9. Windows下使用WSL安装配置Kali/Windows Terminal安装/Win-Kex安装配置(非虚拟机or双系统)

    Windows下使用WSL安装配置Kali/Windows Terminal安装/Win-Kex安装配置(非虚拟机or双系统) 最近因为某些原因含泪拾起自己很久没碰过的CTF,首当其冲是配置环境.首选 ...

  10. 淘宝2013双12攻略:淘宝卖家双12怎么玩?

    淘宝2013双12攻略:淘宝卖家双12怎么玩? 双11刚结束,集市店的伙伴都在抱怨天猫的偏袒,其实作为一个 平台 来说,是不可能做到流量均分的,你所收获的跟你所付出有关.淘宝一直强调生态,所以,双12 ...

最新文章

  1. ssh配置文件ssh_config和sshd_config区别
  2. 自然语言处理的未来之路(周明老师,CCF-GRIR,笔记)
  3. c++查找pair,使用map,unordered_map,vector
  4. 如果外卖APP想窃听我,有几个骚操作?
  5. xtrabackup 备份
  6. BZOJ 1013: [JSOI2008]球形空间产生器sphere
  7. 参考文献查阅网站大全
  8. 电脑如何显示文件后缀名
  9. android电话录音没有声音,Android通话录音未录制来电语音(示例代码)
  10. 如何快速建搭建企业官方网站
  11. IDL文件详解[转]
  12. 电脑小知识cmd命令大全
  13. 编写Java程序,使用 Socket类模拟用户加入 QQ 群时,QQ 小冰发送欢迎消息的场景(用户充当客户端,QQ 小冰充当服务端)
  14. 张正友标定法几个坐标系的意思
  15. PHP快速入门01-初识PHP语言
  16. 2020年防爆电气模拟考试及防爆电气实操考试视频
  17. 国际C语言混乱代码大赛优胜作品详解之“A clock in one line
  18. mtk android平台学习,MTK平台的驱动学习——(阶段1规划篇)
  19. MCP2515调试经验01
  20. 双底形态突破与业绩报表叠加分析!股票量化分析工具QTYX-V2.4.9

热门文章

  1. 软件测试和web前端该怎么选择
  2. Javascript必须掌握的js库
  3. java中this关键字的作用
  4. 盘点 7 个超级 Nice 的微信小程序项目
  5. 全开源-微信小程序(附开源地址)
  6. 软件测试典型缺陷分析,几种典型的软件缺陷分析方法
  7. 动作捕捉协助中国电力科学研究院建立边云协同电力自主巡检系统
  8. STM8S103之独立看门狗和窗口看门狗
  9. Filenet公布第二批打包节点竞选名单
  10. AD14 如何设置PCB板框大小及形状