JS逻辑运算 xxx = xxx || ''
来源:互联网 发布:python hist alpha 编辑:程序博客网 时间:2024/05/20 08:01
1 常规例子
众所周知,逻辑运算符最常用于条件判断的if语句,下面是一个JavaScript的例子
var person = { name: '张三', language: 'JS',}if(person.language == 'JS' || person.language == 'C#'){ console.log('录取了');}else{ console.log('不要');}
输出结果:录取了
2 例外情况
直到有一天我看了前端同事的代码,发现在JavaScript里逻辑运算符竟然还可以这样用:
var person = { name: '张三', language: '',}var language = person.language || '什么都不会';console.log(language);
输出结果:什么都不会
3 问题分析
什么情况,”||”运算返回的难道不应该是”true”或者”false”吗,怎么会返回一个字符串?其实我这是受了C#的影响。
C#作为一门强类型语言,逻辑运算只能用于布尔值,非布尔值必须转换为布尔值才能进行逻辑运算。而JS作为一门弱类型语言,任何类型的数据都能参与逻辑运算,在运算时会隐式转化为布尔值进行判断。
3.1 C#逻辑运算规则
&& :同真为真,只要有一个为假就返回假。|| :同假为假,只要一个为真就返回真。
都是布尔值参与运算,结果一定返回布尔值,我下意识把这个规则也带入了JS。然而不同的是,JS非布尔值也可以参与逻辑运算,结果并不总是返回一个布尔值,所以运算规则是不能完全这么记的。
3.2 JS逻辑运算规则
&& :如果左操作数为假值则返回左操作数,如果左操作数为真值则返回右操作数。|| :如果左操作数为真值返回左操作数,如果左操作数为假值则返回右操作数。
为什么可以用这个规则,下面引用由David Flanagan著淘宝前端团队翻译的《JavaScript权威指南》这本书的一段话:
3.2.1 解释
“&&”:
运算符返回一个“真值”或者“假值”,但并没有说明这个“真值”或者“假值”到底是什么值。运算符首先计算左操作数的值,即首先计算“&&”左侧的表达式。如果计算结果是假值,那么整个表达式的结果也一定是假值,因此”&&”这时简单地返回左操作数的值,而并不会对右操作数进行计算。反过来讲,如果左操作数是真值,那么整个表达式的结果则依赖于右操作数的值。如果右操作数是真值,那么真个表达式的值一定是真值;如果右操作数是假值,那么整个表达式的值一定是假值。因此,当左操作数是真值时,”&&”运算符将计算右操作数的值并将其返回作为整个表达式的结果。
“||”:
它会首先计算第一个操作数的值,也就是说会首先计算左侧的表达式。如果计算结果为真值,那么返回这个真值。否则,再计算第二个操作数的值,即计算右侧的表达式。并返回这个表达式的计算结果。
这里的真值/假值并不是布尔值的意思,再次引用《JavaScript权威指南》的内容进行解释
任意JavaScript值都可以转换成为布尔值。下面这些值会被转换成false:
undefined
null
0
-0
NaN
“” // 双引号表示的空字符串
” // 单引号表示的空字符串
所有其他值,包括所有对象(数组)都会转换成true。false和上面7个可以转换成false的值有时被称作“假值”(falsy value),其他值称作“真值”(truthy value)。JavaScript期望使用一个布尔值的时候,假值会被当成false,真值会被当成true。
3.2.2 验证
简单来说,如果是非布尔值参与逻辑运算,会判断这个值转换布尔值的时候是true还是false,true表示真值,false表示假值。最后返回的并不是布尔值而是这个原始值。
我们来验证一下规则是否正确:
// && :如果左操作数为假值则返回左操作数console.log(null && ({})); // null 为假值,{}为真值,输出 null console.log(NaN && 0); // NaN为假值,0为假值,输出 NaN// && :如果左操作数为真值则返回右操作数console.log(1 && undefined); // 1为真值,undefined为假值,输出 undefinedconsole.log([] && 'hello'); // []为真值,'hello'为真值,输出 'hello'// || :如果左操作数为真值返回左操作数console.log(1 || undefined); // 1为真值,undefined为假值,输出 1console.log([] || 'hello'); // []为真值,'hello'为真值,输出 []// || :如果左操作数为假值则返回右操作数console.log(null || ({})); // null 为假值,{}为真值,输出 {}console.log(NaN || 0); // NaN为假值,0为假值,输出 0
通过验证,发现这些规则确实适用。
4 结论
4.1 与三目运算的关系
现在再去看最初的那个例子,var language = person.language || '什么都不会';
其实是三目运算符的简写形式。
var person = { name: '张三', language: '',}var l0 = person.language || '什么都不会';var l1 = person.language ? person.language : '什么都不会';console.log(l0);console.log(l1);
输出结果:
什么都不会
什么都不会
C#里也有类似的”??”写法,只不过只能用于判断字符串为null时赋予默认值。
class Program { static void Main(string[] args) { var p = new Person { name = "张三", language = null, }; var l0 = p.language ?? "什么都不会"; var l1 = p.language != null ? p.language : "什么都不会"; Console.WriteLine(l0); Console.WriteLine(l1); Console.ReadKey(); } } public class Person { public string name { get; set; } public string language { get; set; } }
输出结果:
什么都不会
什么都不会
4.2 实际运用
“||”:通常用于给假值指定一个默认值,例如前端通过ajax向后端请求数据,返回的数据有可能是null,也有可能是”(空字符串),前端同一处理成”空字符串。
后端返回的数据为
// 后端返回数据var result = { "code": 0, "data": [ { "name": "张三", "language": null, "description": "很懒惰" }, { "name": "李四", "language": "", "description": null }, { "name": "王五", "language": "JS", "description": "" } ]}// 处理var persons = result.data;console.log(JSON.stringify(persons));for (var i = 0; i < persons.length - 1; i++) { var person = persons[i]; person.language = person.language || ''; person.description = person.description || '';}console.log(JSON.stringify(persons));
输出结果:
[ { "name": "张三", "language": null, "description": "很懒惰" }, { "name": "李四", "language": "", "description": null }, { "name": "王五", "language": "JS", "description": "" }]
[ { "name": "张三", "language": "", "description": "很懒惰" }, { "name": "李四", "language": "", "description": "" }, { "name": "王五", "language": "JS", "description": "" }]
- JS逻辑运算 xxx = xxx || ''
- xxx
- xxx
- xxx
- XXX
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- xxx
- XXX
- 查看linux日志文件的实时情况
- 机器学习中非平衡数据集的常用处理方法
- 【Docker】Docker容器与宿主机互相拷贝传递文件
- Ubuntu 安装配置 Tomcat
- WEB项目拾遗之jar包篇
- JS逻辑运算 xxx = xxx || ''
- Java中的单例化
- shell脚本编程教程之三 --- 条件分支编程
- nw.js(node webkit)获取当前app所在的位置
- git diff 指令详解
- 1003. 我要通过!(20)
- 《第六章:对象与设计》阅读笔记
- Selenium操作中文时UnicodeDecodeError: 'utf8' codec can't decode 错误
- 守形数