recursal/MDN huggingface dataset:
void 运算符
========

**`void` 运算符**对给定的表达式进行求值，然后返回 `undefined`。

尝试一下
----

语法
--


```js
void expression
```

描述
--

这个运算符允许在表达式执行完成时，产生（某些地方）期望获得的 `undefined` 值。

`void` 运算符通常只用于获取 `undefined` 的原始值，一般使用 `void(0)`（等同于 `void 0`）。在上述情况中，也可以使用全局变量 `undefined` 来代替。

需要注意考虑 `void` 运算符的优先级，以下加括号的表达式的例子可以帮助你清楚地理解 `void` 操作符的优先级：


```js
void 2 === "2"; // (void 2) === '2'，返回 false
void (2 === "2"); // void (2 === '2')，返回 undefined
```

示例
--

### 立即调用的函数表达式

在使用立即调用的函数表达式时，`function` 关键字不可直接位于语句开头，因为该表达式会被解析为函数声明，并会在解析到代表调用的括号时产生语法错误。如果是匿名函数，那么如果函数被解析为声明，就会立即产生语法错误。


```js
function iife() {
  console.log("Executed!");
}(); // SyntaxError: Unexpected token ')'

function () {
  console.log("Executed!");
}(); // SyntaxError: Function statements require a function name
```


为了使函数被解析为表达式，`function` 关键字必须出现在一个只接受表达式而不是语句的位置。这可以通过在关键字前加一个一元运算符来实现，它只接受表达式作为操作数。函数调用的优先级比一元运算符高，所以它将被首先执行。它的返回值（几乎总是 `undefined`）将被传递给一元运算符，然后立即被丢弃。

在所有的一元运算符中，`void` 提供了最好的语义，因为它明确表示函数调用的返回值应该被丢弃。


```js
void (function () {
  console.log("Executed!");
})();

// Output: "Executed!"
```


这比用圆括号包裹函数表达式要长一些，圆括号的作用是强迫 `function` 关键字被解析为表达式的开始，而不是语句。


```js
(function () {
  console.log("Executed!");
})();
```

### JavaScript URI

当用户点击一个以 `javascript:` 开头的 URI 时，它会执行 URI 中的代码，然后用返回的值替换页面内容，除非返回的值是 `undefined`。`void` 运算符可用于返回 `undefined`。例如：


```html
<a href="javascript:void(0);"> 这个链接点击之后不会做任何事情 </a>

<a href="javascript:void(document.body.style.backgroundColor='green');">
  点击这个链接会让页面背景变成绿色。
</a>
```


**备注：** 利用 `javascript:` 伪协议来执行 JavaScript 代码是不推荐的，推荐的做法是为链接元素绑定事件。

### 在箭头函数中避免泄漏

箭头函数标准中，允许在函数体不使用括号来直接返回值。如果右侧调用了一个原本没有返回值的函数，其返回值改变后，则会导致非预期的副作用。安全起见，当函数返回值不会被使用到的时候，应该使用 `void` 运算符，来确保 API 改变时，并不会改变箭头函数的行为。


```js
button.onclick = () => void doSomething();
```


这确保了当 `doSomething` 的返回值从 `undefined` 变为 `true` 的时候，不会改变代码的行为。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-void-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `undefined`
逻辑非（!）
======

**逻辑非**（`!`，逻辑连接取反）运算符将真值或假值转换为对应的相反值，经常用于布尔（逻辑）值。当与非布尔值使用时，如果其操作数可以转化为 `true`，则返回 `false`，否则返回 `true`。

尝试一下
----

语法
--


```js
!expr
```

描述
--

如果其操作数可以转化为 `true`，则返回 `false`，否则返回 `true`。

能够转化为 `true` 的值叫做真值，能够转化为 `false` 的值叫做假值。

能够转化为 false 的表达式的示例如下：

* `null`；
* `NaN`；
* `0`；
* 空字符串（`""` 或 `''` 或 ````）；
* `undefined`。

尽管 `!` 运算符可以与非布尔操作数一起使用，但它仍然被认为是一个布尔运算符，因为它的返回值总是可以被转换为布尔基本类型。要明确地将其返回值（或任何一般的表达式）转换为相应的布尔值，请使用双非运算符（`!!`）或 `Boolean` 构造函数。

示例
--

### 使用非运算符

下列代码展示了 `!`（逻辑非）运算符的用法。


```js
!true; // !t returns false
!false; // !f returns true
!""; // !f returns true
!"Cat"; // !t returns false
```

### 双非运算符（`!!`）

可以使用几个非运算符串联起来，明确地强制将任何值转换为相应的布尔基本类型。这种转换是基于值的“真实性”或“虚假性”（详见真值和假值）。

也可以使用 `Boolean` 函数完成转换。


```js
!!true; // !!truthy returns true
!!{}; // !!truthy returns true: any object is truthy...
!!new Boolean(false); // ...even Boolean objects with a false .valueOf()!
!!false; // !!falsy returns false
!!""; // !!falsy returns false
!!Boolean(false); // !!falsy returns false
```

### 非运算符转换

下述涉及到**布尔值**的运算：


```js
!!bCondition
```


总是与此表达式相同：


```js
bCondition
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-logical-not-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Boolean`
* 真值
* 假值
不相等（!=）
=======

不相等运算符（`!=`）检查其两个操作数是否不相等，并返回布尔结果。与严格不相等运算符不同，它会转换并比较不同类型的操作数。

尝试一下
----

语法
--


```js
x != y
```

描述
--

不等式运算符检查其操作数是否不相等。这是相等运算符的否定，因此以下两行将始终给出相同的结果：


```js
x != y;

!(x == y);
```


有关比较算法的详细信息，请参见相等运算符的页面。

与相等运算符一样，不相等运算符将尝试转换和比较不同类型的操作数：


```js
3 != "3"; // false
```


为避免这种情况，并要求将不同类型视为不同，请使用严格不相等运算符：


```js
3 !== "3"; // true
```

示例
--

### 没有类型转换的比较


```js
1 != 2; // true
"hello" != "hola"; // true

1 != 1; // false
"hello" != "hello"; // false
```

### 有类型转换的比较


```js
"1" != 1; // false
1 != "1"; // false
0 != false; // false
0 != null; // true
0 != undefined; // true
0 != !!null; // false，看看逻辑非运算符
0 != !!undefined; // false，看看逻辑非运算符
null != undefined; // false

const number1 = new Number(3);
const number2 = new Number(3);
number1 != 3; // false
number1 != number2; // true
```

### 比较对象


```js
const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 != object2); // true
console.log(object1 != object1); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 相等运算符
* 严格相等运算符
* 严格不相等运算符
乘法（\*）
======

**乘法**（**`*`**）运算符计算操作数的乘积。

尝试一下
----

语法
--


```js
x \* y
```

示例
--

### 数值乘法


```js
2 \* 2; // 4
-2 \* 2; // -4
```

### 与 Infinity 相乘


```js
Infinity \* 0; // NaN
Infinity \* Infinity; // Infinity
```

### 非数值乘法


```js
"foo" \* 2; // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-multiplicative-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 加法运算符
* 减法运算符
* 除法运算符
* 取余运算符
* 幂运算符
* 自增运算符
* 自减运算符
* 一元减运算符
* 一元加运算符
小于等于（<=）
========

小于等于运算符（`<=`）在左操作数小于等于右操作数时返回 `true`，否则返回 `false`。

尝试一下
----

语法
--


```js
x <= y
```

描述
--

操作数比较使用与小于运算符相同的算法，除了相等的值（在尝试转换后）会返回 `true`。

示例
--

### 字符串与字符串比较


```js
console.log("a" <= "b"); // true
console.log("a" <= "a"); // true
console.log("a" <= "3"); // false
```

### 字符串与数值比较


```js
console.log("5" <= 3); // false
console.log("3" <= 3); // true
console.log("3" <= 5); // true

console.log("hello" <= 5); // false
console.log(5 <= "hello"); // false
```

### 数值与数值比较


```js
console.log(5 <= 3); // false
console.log(3 <= 3); // true
console.log(3 <= 5); // true
```

### 数值与大整型比较


```js
console.log(5n <= 3); // false
console.log(3 <= 3n); // true
console.log(3 <= 5n); // true
```

### 比较 Boolean、null、undefined 和 NaN


```js
console.log(true <= false); // false
console.log(true <= true); // true
console.log(false <= true); // true

console.log(true <= 0); // false
console.log(true <= 1); // true

console.log(null <= 0); // true
console.log(1 <= null); // false

console.log(undefined <= 3); // false
console.log(3 <= undefined); // false

console.log(3 <= NaN); // false
console.log(NaN <= 3); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 大于运算符
* 大于等于运算符
* 小于运算符
圆括号运算符
======

圆括号运算符 `( )` 用于控制表达式中的运算优先级。

尝试一下
----

语法
--


```js
(expression)
```

说明
--

圆括号运算符由一对圆括号组成，包裹表达式和子表达式用来覆盖常规的运算符优先级，达到低优先级的表达式比高优先级的表达式更早运算。

示例
--

下面的代码展示了加法运算先于乘法运算的情况。


```js
const a = 1;
const b = 2;
const c = 3;

// 默认优先级
a + b \* c; // 7
// 默认运算顺序同下
a + (b \* c); // 7

// 现在优先考虑乘法之前的加法
(a + b) \* c; // 9

// 这相当于
a \* c + b \* c; // 9
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-grouping-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 运算符优先级
* `delete`
* `typeof`
按位非（~）
======

按位非运算符（`~`）将操作数的位反转。如同其他位运算符一样，它将操作数转化为 32 位的有符号整型。

尝试一下
----

语法
--


```js
~a
```

描述
--

操作数被转换为 32 位有符号整型，并以一系列比特（0 和 1）表示。超过 32 位的数字将丢弃其最高有效位。如下例子中，超过 32 位的整数将转换为 32 位整数：
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```


运算结果的每一位数都由操作数相应位反转而来。

`NOT` 运算的真值表如下所示：

| a | NOT a |
| --- | --- |
| 0 | 1 |
| 1 | 0 |
```

 9 (base 10) = 00000000000000000000000000001001 (base 2)
               --------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
```


32 位有符号整数操作数根据补码运算规则进行反转，也就是说，最高有效位表示负数。

按位非运算时，任何数字 `x` 的运算结果都是 `-(x + 1)`。例如，`~-5` 运算结果为 `4`。

请注意，由于数字 `~-1` 和 `~4294967295`（232 - 1）均使用 32 位表示形式，它们的运算结果均为 `0`。

示例
--

### 使用按位取反


```js
~0; // -1
~-1; // 0
~1; // -2
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-bitwise-not-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* JavaScript 指南：位运算符
严格不相等（!==）
==========

严格不相等运算符（`!==`）检查它的两个对象是否不相等，返回一个布尔结果。与不相等运算符不同，严格不相等运算符总是认为不同类型的对象是不同的。

尝试一下
----

语法
--


```js
x !== y
```

描述
--

严格不相等运算符检查其对象是否不相等。它是严格相等运算符的否定，因此下面两行总是会给出相同的结果：


```js
x !== y;

!(x === y);
```


有关比较算法的详细信息，请参阅严格相等运算符的页面。

与严格相等运算符一样，严格不相等算符始终认为不同类型的对象是不同的：


```js
3 !== "3"; // true
```

示例
--

### 比较相同类型的对象


```js
"hello" !== "hello"; // false
"hello" !== "hola"; // true

3 !== 3; // false
3 !== 4; // true

true !== true; // false
true !== false; // true

null !== null; // false
```

### 比较不同类型的操作数


```js
"3" !== 3; // true
true !== 1; // true
null !== undefined; // true
```

### 比较对象


```js
const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 !== object2); // true
console.log(object1 !== object1); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 相等运算符
* 不相等运算符
* 严格相等运算符
逻辑与赋值（&&=）
==========

**逻辑与赋值**（`x &&= y`）运算仅在 `x` 为真值时为其赋值。

尝试一下
----

语法
--


```js
expr1 &&= expr2
```

描述
--

逻辑与的*短路运算*意味着 `x &&= y` 与下式等价：


```js
x && (x = y);
```


如果左操作数不为真值，则由于逻辑与运算符的短路运算，不进行赋值操作。例如，由于 `x` 为 `const`（常量），以下式子不会抛出错误：


```js
const x = 0;
x &&= 2;
```


也不会触发 setter 函数：


```js
const x = {
  get value() {
    return 0;
  },
  set value(v) {
    console.log("调用了 setter");
  },
};
x.value &&= 2;
```


实际上，如果 `x` 不为真值，则根本不会对 `y` 求值。


```js
const x = 0;
x &&= console.log("y 进行了求值");
// 什么都不会输出
```

示例
--

### 使用逻辑与赋值


```js
let x = 0;
let y = 1;

x &&= 0; // 0
x &&= 1; // 0
y &&= 1; // 1
y &&= 0; // 0
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 逻辑与（&&）
* 空值合并运算符（`??`）
* 按位与赋值（`&=`）
* 真值
* 假值
按位与赋值（&=）
=========

按位与赋值运算符（`&=`）使用两个操作数的二进制表示，对它们进行按位与运算并将结果赋值给变量。

尝试一下
----

语法
--


```js
x &= y // x = x & y
```

示例
--

### 使用按位与赋值


```js
let a = 5;
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
a &= 2; // 0
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* JS 指南中的赋值运算符
* 按位与运算符
yield\*
=======

**`yield*` 表达式**用于委托给另一个`generator` 或可迭代对象。

语法
--
```

 yield* [[expression]];
```


`expression`

返回一个可迭代对象的表达式。

描述
--

`yield*` 表达式迭代操作数，并产生它返回的每个值。

`yield*` 表达式本身的值是当迭代器关闭时返回的值（即`done`为`true`时）。

示例
--

### 委托给其他生成器

以下代码中，`g1()` `yield` 出去的每个值都会在 `g2()` 的 `next()` 方法中返回，就像那些 `yield` 语句是写在 `g2()` 里一样。


```js
function\* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function\* g2() {
  yield 1;
  yield\* g1();
  yield 5;
}

var iterator = g2();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

### 委托给其他可迭代对象

除了生成器对象这一种可迭代对象，`yield*` 还可以 `yield` 其他任意的可迭代对象，比如说数组、字符串、`arguments` 对象等等。


```js
function\* g3() {
  yield\* [1, 2];
  yield\* "34";
  yield\* arguments;
}

var iterator = g3(5, 6);

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

### `yield*` 表达式的值

`yield*` 是一个表达式，不是语句，所以它会有自己的值。


```js
function\* g4() {
  yield\* [1, 2, 3];
  return "foo";
}

var result;

function\* g5() {
  result = yield\* g4();
}

var iterator = g5();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true },
// 此时 g4() 返回了 { value: "foo", done: true }

console.log(result); // "foo"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 迭代器协议
* `function*`
* `function*` 表达式
* `yield`
左移 (<<)
=======

**左移操作符 (`<<`)** 将第一个操作数向左移动指定位数，左边超出的位数将会被清除，右边将会补零。

尝试一下
----

语法
--
```

a << b
```

描述
--

左移操作符将第一个操作数向左移动指定位数，左边超出的位数将会被清除，右边将会补零。

例如， `9 << 2` 得出 36：


```js
     9 (十进制): 00000000000000000000000000001001 (二进制)
                 --------------------------------

9 << 2 (十进制): 00000000000000000000000000100100 (二进制) = 36 (十进制)
```


 移动任意数字 `x` 至左边 `y` 位，得出 `x * 2 ** y`。
 所以例如：`9 << 3` 等价于 `9 * 2³ = 9 * 8 = 72`。

示例
--

### 使用左移


```js
9 << 3; // 72

// 9 \* 2³ = 9 \* 8 = 72
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-left-shift-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* Bitwise operators in the JS guide
* Left shift assignment operator
按位异或（^）
=======

**按位异或**（**`^`**）运算符在两个操作数有且仅有一个对应的二进制位为 `1` 时，该位的结果值为 `1`。

尝试一下
----

语法
--


```js
a ^ b
```

描述
--

操作数被转换为 32 位整数并由一系列二进制位（0 和 1）表示。超过 32 位的数字会丢弃其最高有效位。例如，以下超过 32 位的整数将被转换为 32 位整数：
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```


第一个操作数中的每个位都与第二个操作数中的相应位配对：*第一位*到*第一位*、*第二位*到*第二位*，以此类推。

运算符应用于每一对位，结果按位构造。

异或或运算的真值表为：

| a | b | a XOR b |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
```

     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
```


将任意数字 `x` 与 `0` 进行按位异或运算得到 `x`。

示例
--

### 使用按位异或


```js
// 9 (00000000000000000000000000001001)
// 14 (00000000000000000000000000001110)

14 ^ 9;
// 7 (00000000000000000000000000000111)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseXORExpression |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* JS 指南中的位运算符
* 按位异或赋值运算符
一元加（+）
======

**一元加**（**`+`**）运算符在其操作数之前并计算其操作数，但会尝试将其转换为数字，如果它还不是的话。

尝试一下
----

语法
--


```js
+x
```

描述
--

虽然一元减（`-`）也可以转换非数字，但一元加是将某些东西转换为数字的最快和首选方法，因为它不对数字执行任何其他操作。它可以转换整数和浮点数的字符串表示形式，以及非字符串值 `true`、`false` 和 `null`。支持十进制和十六进制（以 `0x` 为前缀）格式的整数。支持负数（但不适用于十六进制）。对 BigInt 值使用该运算符会引发 TypeError。如果它无法解析特定值，它将计算为 `NaN`。

示例
--

### 数字用法


```js
const x = 1;
const y = -1;

console.log(+x);
// 1
console.log(+y);
// -1
```

### 非数字用法


```js
+true  // 1
+false // 0
+null  // 0
+function (val) { return val; } // NaN
+1n    // throws TypeError: Cannot convert BigInt value to number
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-unary-plus-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 加法运算符
* 减法运算符
* 除法运算符
* 乘法运算符
* 取余运算符
* 求幂运算符
* 自增运算符
* 自减运算符
* 一元减运算符
条件（三元）运算符
=========

**条件（三元）运算符**是 JavaScript 唯一使用三个操作数的运算符：一个条件后跟一个问号（`?`），如果条件为真值，则执行冒号（`:`）前的表达式；若条件为假值，则执行最后的表达式。该运算符经常当作 `if...else` 语句的简捷形式来使用。

尝试一下
----

语法
--


```js
condition ? exprIfTrue : exprIfFalse
```

### 参数

`condition`

计算结果用作条件的表达式。

`exprIfTrue`

如果 `condition` 的计算结果为真值（等于或可以转换为 `true` 的值），则执行该表达式。

`exprIfFalse`

如果 `condition` 为假值（等于或可以转换为 `false` 的值）时执行的表达式。

描述
--

除了 `false`，可能的假值表达式还有：`null`、`NaN`、`0`、空字符串（`""`）和 `undefined`。如果 `condition` 是其中任何一个，那么条件表达式的结果就是 `exprIfFalse` 表达式执行的结果。

示例
--

### 简单的例子


```js
const age = 26;
const beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"
```

### 处理 null 值

一个常见的用法是处理可能为 `null` 的值：


```js
const greeting = (person) => {
  const name = person ? person.name : "stranger";
  return `Howdy, ${name}`;
};

console.log(greeting({ name: "Alice" })); // "Howdy, Alice"
console.log(greeting(null)); // "Howdy, stranger"
```

### 条件链

三元运算符是右结合的，这意味着它可以按以下方式“链接”起来，类似于 `if … else if … else if … else` 链：


```js
function example() {
  return condition1
    ? value1
    : condition2
      ? value2
      : condition3
        ? value3
        : value4;
}
```


这等价于以下 `if...else` 链。


```js
function example() {
  if (condition1) {
    return value1;
  } else if (condition2) {
    return value2;
  } else if (condition3) {
    return value3;
  } else {
    return value4;
  }
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-conditional-operator |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* if 语句
* 空值合并运算符（`??`）
* 可选链运算符（`?.`）
* 在代码中做决定——条件语句
* 表达式与运算符
逻辑与（&&）
=======

当且仅当所有操作数为 `true` 时，一组布尔操作数的**逻辑与**（**`&&`**，逻辑连接）运算结果为 `true`，否则为 `false`。

一般来说，当从左到右求值时，该操作符返回第一个假值操作数的值；如果它们都是真值，则返回最后一个操作数的值。

尝试一下
----

语法
--


```js
expr1 && expr2
```

描述
--

逻辑与（`&&`）运算符从左到右对操作数求值，遇到第一个假值操作数时立即返回；如果所有的操作数都是真值，则返回最后一个操作数的值。

能够转化为 `true` 的值叫做真值，能够转化为 `false` 的值叫做假值。

能够转化为 false 的表达式的示例如下：

* `false`；
* `null`；
* `NaN`；
* `0`；
* 空字符串（`""` 或 `''` 或 ````）；
* `undefined`。

与运算符会保留所有非布尔值，并原样返回它们：


```js
result = "" && "foo"; // 结果被赋值为 ""（空字符串）
result = 2 && 0; // 结果被赋值为 0
result = "foo" && 4; // 结果被赋值为 4
```


尽管 `&&` 运算符可以与非布尔操作数一起使用，但它仍然被认为是一个布尔运算符，因为它的返回值总是可以被转换为布尔基本类型。要明确地将其返回值（或任何一般的表达式）转换为相应的布尔值，请使用双`非运算符`或 `Boolean` 构造函数。

### 短路求值

逻辑与是一种短路运算符。当每个操作数被转换为布尔值时，如果发现一个转换的结果是 `false`，那么逻辑与运算符就会停止，并返回该假操作数的原始值；它**不会**对任何其余的操作数求值。

考虑如下伪代码。
```

(some falsy expression) && expr
```


`expr` 部分**永远不会被求值**，因为第一个操作数 `(some falsy expression)` 被求值为假值。如果 `expr` 是一个函数，它将不会被调用。查看如下示例：


```js
function A() {
  console.log("调用了 A");
  return false;
}
function B() {
  console.log("调用了 B");
  return true;
}
console.log(A() && B());
// 由于调用了 A 函数，故会输出“调用了 A”到控制台，
// && 求值结果为 false（A 函数返回 false），然后输出 false 到控制台；
// 与运算符在这里短路，忽略了 B 函数
```

### 运算符优先级

与运算符的优先级高于或运算符，这意味着 `&&` 运算符在 `||` 运算符前执行（参见运算符优先级）。


```js
true || (false && false); // true
true && (false || false); // false
2 === 3 || (4 < 0 && 1 === 1); // false
```

示例
--

### 使用与运算符

下列代码展示了 `&&`（逻辑与）运算符的用法。


```js
a1 = true && true; // t && t returns true
a2 = true && false; // t && f returns false
a3 = false && true; // f && t returns false
a4 = false && 3 === 4; // f && f returns false
a5 = "Cat" && "Dog"; // t && t returns "Dog"
a6 = false && "Cat"; // f && t returns false
a7 = "Cat" && false; // t && f returns false
a8 = "" && false; // f && f returns ""
a9 = false && ""; // f && f returns false
```

### 布尔值转化规则

#### 与运算符转化为或运算符

下述涉及到**布尔**运算符的运算：


```js
bCondition1 && bCondition2
```


总是与此表达式相同：


```js
!(!bCondition1 || !bCondition2)
```


#### 或运算符转化为与运算符

下述涉及到**布尔**运算符的运算：


```js
bCondition1 || bCondition2
```


总是与此表达式相同：


```js
!(!bCondition1 && !bCondition2)
```

### 去除嵌套的括号

由于逻辑表达式是从左到右进行求值的，只要遵循一定的规则，总是可以从一个复杂的表达式中删除括号。

下述涉及到**布尔**运算符的复杂运算：


```js
bCondition1 || (bCondition2 && bCondition3)
```


总是与此表达式相同：


```js
bCondition1 || bCondition2 && bCondition3
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalANDExpression |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Boolean`
* 真值
* 假值
按位异或赋值 (^=)
===========

按位异或赋值操作符 (`^=`) 使用二进制表示操作数，进行一次按位异或操作并赋值。

尝试一下
----

语法
--
```

Operator: x ^= y
Meaning:  x  = x ^ y
```

示例
--

### 使用按位异或赋值


```js
let a = 5; // 00000000000000000000000000000101
a ^= 3; // 00000000000000000000000000000011

console.log(a); // 00000000000000000000000000000110
// 6

let b = 5; // 00000000000000000000000000000101
b ^= 0; // 00000000000000000000000000000000

console.log(b); // 00000000000000000000000000000101
// 5
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* Assignment operators in the JS guide
* Bitwise XOR operator
大于等于（>=）
========

大于等于运算符（`>=`）在左操作数大于等于右操作数时返回 `true`，否则返回 `false`。

尝试一下
----

语法
--


```js
x >= y
```

描述
--

操作数比较使用与小于运算符相同的算法，除了两个操作数为相等的值（在尝试转换后）会返回 `true`。

示例
--

### 字符串与字符串比较


```js
console.log("a" >= "b"); // false
console.log("a" >= "a"); // true
console.log("a" >= "3"); // true
```

### 字符串与数值比较


```js
console.log("5" >= 3); // true
console.log("3" >= 3); // true
console.log("3" >= 5); // false

console.log("hello" >= 5); // false
console.log(5 >= "hello"); // false
```

### 数值与数值比较


```js
console.log(5 >= 3); // true
console.log(3 >= 3); // true
console.log(3 >= 5); // false
```

### 数值与大整型比较


```js
console.log(5n >= 3); // true
console.log(3 >= 3n); // true
console.log(3 >= 5n); // false
```

### 比较 Boolean、null、undefined 和 NaN


```js
console.log(true >= false); // true
console.log(true >= true); // true
console.log(false >= true); // false

console.log(true >= 0); // true
console.log(true >= 1); // true

console.log(null >= 0); // true
console.log(1 >= null); // true

console.log(undefined >= 3); // false
console.log(3 >= undefined); // false

console.log(3 >= NaN); // false
console.log(NaN >= 3); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* 大于运算符
* 小于运算符
* 小于等于运算符
逻辑或赋值（||=）
==========

逻辑或赋值（`x ||= y`）运算仅在 `x` 为假值时为其赋值。

尝试一下
----

语法
--


```js
expr1 ||= expr2
```

描述
--

逻辑或的*短路运算*意味着 `x ||= y` 与下式等价：


```js
x || (x = y);
```


如果左操作数不为假值，则由于逻辑或运算符的短路运算，不进行赋值操作。例如，由于 `x` 为 `const`（常量），以下式子不会抛出错误：


```js
const x = 1;
x ||= 2;
```


也不会触发 setter 函数：


```js
const x = {
  get value() {
    return 1;
  },
  set value(v) {
    console.log("调用了 setter");
  },
};

x.value ||= 2;
```


实际上，如果 `x` 为真值，则根本不会对 `y` 求值。


```js
const x = 1;
x ||= console.log("y 进行了求值");
// 什么都不会输出
```

示例
--

### 设定默认内容

当“lyrics”元素为空时，则显示默认值：


```js
document.getElementById("lyrics").textContent ||= "没有歌词。";
```


在这里，短路运算特别有用，因为元素不会产生不必要的更新，也不会引起诸如额外的解析、渲染、失去焦点等副作用。

注意：请注意检查 API 返回的值。如果返回的是空字符串（是假值），则必须使用 `||=`，以显示“没有歌词。”而不是空内容。然而，如果接口返回 `null` 或 `undefined`，则应该使用 `??=`（空值合并赋值）运算符代替空白内容。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 逻辑或（||）
* 空值合并运算符（`??`）
* 按位或赋值（`|=`）
* 真值
* 假值