原文: https://blog.mariusschulz.com/2016/05/25/the-andand-and-operator-in-javascript

The && and || Operator in JavaScript

-------------------------------------------------

Similar to other C-like programming languages, JavaScript defines the two operators && and || which represent the logical AND and OR operations, respectively. Using only the two boolean values true and false, we can generate the following truth tables:

// Logical AND operation
true && true; // true
true && false; // false
false && true; // false
false && false; // false // Logical OR operation
true || true; // true
true || false; // true
false || true; // true
false || false; // false

If applied to boolean values, the && operator only returns true when both of its operands are true (and false in all other cases), while the || operator only returns false when both of its operands are false (and true in all other cases).

Using Logical Operators with Non-Boolean Values

In JavaScript, the logical operators have different semantics than other C-like languages, though. They can operate on expressions of any type, not just booleans. Also, the logical operators do not always return a boolean value, as the specification points out in section 12.12:

The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

The following examples showcase some values produced by && and ||:

"foo" && "bar"; // "bar"
"bar" && "foo"; // "foo"
"foo" && ""; // ""
"" && "foo"; // "" "foo" || "bar"; // "foo"
"bar" || "foo"; // "bar"
"foo" || ""; // "foo"
"" || "foo"; // "foo"

Both && and || result in the value of (exactly) one of their operands:

  • A && B returns the value A if A can be coerced into false; otherwise, it returns B.
  • A || B returns the value A if A can be coerced into true; otherwise, it returns B.

They select one of their operands, as noted by Kyle Simpson in his You Don't Know JS series:

In fact, I would argue these operators shouldn't even be called "logical operators", as that name is incomplete in describing what they do. If I were to give them a more accurate (if more clumsy) name, I'd call them "selector operators," or more completely, "operand selector operators."

Control Flow Structures and Truthy Values

In practice, you might not even notice that && and || don't always produce a boolean value. The body of control flow structures like if-statements and loops will be executed when the condition evaluates to a "truthy" value, which doesn't have to be a proper boolean:

let values = [1, 2, 3];

while (values.length) {
console.log(values.pop());
} // 3
// 2
// 1

So when is a value considered "truthy"? In JavaScript, all values are considered "truthy", except for the following six "falsy" values:

  • false
  • undefined
  • null
  • NaN
  • 0 (both +0 and -0)
  • ""

The above while-loop works because after popping the last element, values.length returns the "falsy" value 0. Therefore, the loop body won't be executed and the loop terminates.

Truthy and Falsy Return Values

Let's look at an example where it actually matters that && and || don't necessarily produce a boolean value. Imagine you're developing a web application. Users can be signed out, in which case the user object is null, or they can be signed in, in which case the user object exists and has an isAdmin property.

If you wanted to check whether the current user is an administrator, you would first check whether the user is authenticated (that is, user is not null). Then, you would access the isAdmin property and check whether it's "truthy":

let user = { isAdmin: true };

// ...

if (user && user.isAdmin) {
// ...
}

You might even consider extracting the expression user && user.isAdmin into a separate isAdministrator function so you can use it in multiple places without repeating yourself:

function isAdministrator(user) {
return user && user.isAdmin;
} let user = { isAdmin: true }; if (isAdministrator(user)) {
// ...
}

For user objects with a boolean isAdmin property, either true or false will be returned, just as intended:

isAdministrator({ isAdmin: true });  // true
isAdministrator({ isAdmin: false }); // false

But what happens if the user object is null?

isAdministrator(null); // null

The expression user && user.isAdmin evaluates to null, its first operand, because usercontains a "falsy" value. Now, a function called isAdministrator should only return boolean values, as the prefix is in the name suggests.

Coercion to Boolean Values

In JavaScript, a common way to coerce any value into a boolean is to apply the logical NOT operator ! twice:

function isAdministrator(user) {
return !!(user && user.isAdmin);
}

The ! operator, produces the value false if its single operand can be coerced into true; otherwise, it returns true. The result is always a proper boolean, but the truthiness of the operand is flipped. Applying the ! operator twice undoes the flipping:

!!true = !false = true
!!false = !true = false !!0 = !true = false
!!1 = !false = true

Another option would've been to call the Boolean function, which is a slightly more explicit way to convert a given value to a proper boolean value:

function isAdministrator(user) {
return Boolean(user && user.isAdmin);
}

Conclusion

In JavaScript, && and || don't always produce a boolean value. Both operators always return the value of one of their operand expressions. Using the double negation !! or the Booleanfunction, "truthy" and "falsy" values can be converted to proper booleans.

【转】The && and || Operator in JavaScript的更多相关文章

  1. What is the !! (not not) operator in JavaScript?

    What is the !! (not not) operator in JavaScript? 解答1 Coerces强制 oObject to boolean. If it was falsey ...

  2. The tilde ( ~ ) operator in JavaScript

    From the JavaScript Reference on MDC, ~ (Bitwise NOT) Performs the NOT operator on each bit. NOT a y ...

  3. [TypeScript] Use the JavaScript “in” operator for automatic type inference in TypeScript

    Sometimes we might want to make a function more generic by having it accept a union of different typ ...

  4. JavaScript简易教程(转)

    原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...

  5. JavaScript constructors, prototypes, and the `new` keyword

    Are you baffled(阻碍:使迷惑) by the new operator in JavaScript? Wonder what the difference between a func ...

  6. JavaScript简易教程

    这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScript的世界——前提是你有一些编程经验的话.本文试图描述这门语言的最小子集.我给这个子集起名叫做“Java ...

  7. 【转】Expressions versus statements in JavaScript

    原文地址:http://www.2ality.com/2012/09/expressions-vs-statements.html Update 2012-09-21: New in Sect. 4: ...

  8. javascript prototype原型链的原理

    javascript prototype原型链的原理 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/javasc ...

  9. JavaScript技巧手冊

    js小技巧 每一项都是js中的小技巧,但十分的有用! 1.document.write(""); 输出语句  2.JS中的凝视为//  3.传统的HTML文档顺序是:documen ...

随机推荐

  1. mac 远程桌面连接分享

    mac 远程桌面连接分享 8.0版本 https://pan.baidu.com/s/1wgVvAmQreGwYZAhLST764w 10.0版本 https://pan.baidu.com/s/1Y ...

  2. Java容器类解析

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,默认长度是十 查询快,增删慢 add()时判断是否数组越界,数组扩容为原来的1.5倍 线程 ...

  3. CentOS6安装后的常见基础优化

    1.SSH优化 编辑/etc/ssh/sshd_config配置文件 //全部都应该设置为no /etc/ssh/sshd_config //服务端配置文件 /etc/ssh/ssh_config / ...

  4. OpenStack 认证服务 KeyStone 服务注册(六)

    一)检查keystone是否安装配置成功 1.1删除环境变量的配置 unset OS_AUTH_URL redhat 1.2 请求令牌认证 admin用户,请求认证令牌 openstack --os- ...

  5. phpqrcode生成带logo的二维码图片

    <?php //include_once('lib/QrReader.php'); //$qrcode = new QrReader('201708211144474410.jpg'); //图 ...

  6. 【linux入门必备】小白需要掌握的基础知识_不定期更新

    因为博主对linux掌握暂时不需要太精通,遇到一个记录一个. 零碎 知识点: 杂类常用命令: 模糊匹配补齐 TAB 系统相关命令: 查阅手册 man 更新软件 sudo apt-get update ...

  7. 洛谷—— P1908 逆序对

    https://www.luogu.org/problem/show?pid=1908 题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏, ...

  8. Linux用户密码文件/etc/shadow相关

    (1).密码文件 [root@xuexi ~]# head -3 /etc/shadow root:$6$kcgcu794R0VP3fDL$aYN8XUbtWvZ4QQtT2xVW.N2CgE3YLP ...

  9. Flask实战第62天:帖子详情页布局

    在templates/front/下创建详情页面front_pdetail.html 编辑front.views.py创建详情页的视图函数 from flask import abort ... @b ...

  10. RUP你知道多少?

    RUP 相信学UML的同学,对此都很耳熟,当然也眼熟,可是,对于RUP,你了解多少呢? 首先,什么是RUP? RUP是Rational UnifiedProcess,统一软件开发过程,是一个面向对象且 ...