This commit is contained in:
2026-07-06 20:14:37 +08:00
commit 00163f484e

412
JavaScript.md Normal file
View File

@@ -0,0 +1,412 @@
## 交互alert、prompt 和 confirm
```js
alert("Hello");
result = prompt(title, [default]);
result = confirm(question); // true | false
```
## 类型转换
### 字符串转换
我们也可以显式地调用 `String(value)` 来将 value 转换为字符串类型:
```js
let value = true;
alert(typeof value); // boolean
value = String(value); // 现在,值是一个字符串形式的 "true"
alert(typeof value); // string
```
### 数字型转换
在算术函数和表达式中,会自动进行 number 类型转换。
```js
alert( "6" / "2" ); // 3, string 类型的值被自动转换成 number 类型后进行计算
```
显式转换。
```js
let str = "123";
alert(typeof str); // string
let num = Number(str); // 变成 number 类型 123
alert(typeof num); // number
```
`Number` 类型的转换规则:
| 值 | 变成…… |
| :-------------- | :----------------------------------------------------------- |
| `undefined` | `NaN` |
| `null` | `0` |
| `true 和 false` | `1` and `0` |
| `string` | 去掉首尾空白字符(空格、换行符 `\n`、制表符 `\t` 等)后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 `0`。否则,将会从剩余字符串中“读取”数字。当类型转换出现 error 时返回 `NaN`。 |
### 布尔型转换
它发生在逻辑运算中,也可以通过调用 Boolean(value) 显式地进行转换。
转换规则如下:
- 直观上为“空”的值(如 `0`、空字符串、`null``undefined``NaN`)将变为 `false`
- 其他值变成 `true`
## 基础运算符,数学运算
### 术语:“一元运算符”,“二元运算符”,“运算元”
运算元:比如说乘法运算 `5 * 2`,有两个运算元:左运算元 `5` 和右运算元 `2`。有时候人们也称其为“参数”而不是“运算元”。
如果一个运算符对应的只有一个运算元,那么它是 **一元运算符**。比如说一元负号运算符unary negation`-`,它的作用是对数字进行正负转换:
```js
let x = 1;
x = -x;
alert( x ); // -1一元负号运算符生效
```
如果一个运算符拥有两个运算元,那么它是 **二元运算符**。减号还存在二元运算符形式:
```js
let x = 1, y = 3;
alert( y - x ); // 2二元运算符减号做减运算
```
### 数学运算
支持以下数学运算:
- 加法 `+`,
- 减法 `-`,
- 乘法 `*`,
- 除法 `/`,
- 取余 `%`,
- 求幂 `**`.
### 数字转化,一元运算符 `+`
加号 `+` 有两种形式。一种是上面我们刚刚讨论的二元运算符,还有一种是一元运算符。
一元运算符加号,或者说,加号 `+` 应用于单个值,对数字没有任何作用。但是如果运算元不是数字,加号 `+` 则会将其转化为数字。
```JS
let apples = "2";
let oranges = "3";
alert( apples + oranges ); // "23",二元运算符加号合并字符串
```
```JS
let apples = "2";
let oranges = "3";
// 在二元运算符加号起作用之前,所有的值都被转化为了数字
alert( +apples + +oranges ); // 5
// 更长的写法
// alert( Number(apples) + Number(oranges) ); // 5
```
### 逗号运算符
逗号运算符能让我们处理多个表达式,使用 , 将它们分开。每个表达式都运行了,但是只有最后一个的结果会被返回。
```js
let a = (1 + 2, 3 + 4);
alert( a ); // 73 + 4 的结果)
// 一行上有三个运算符
for (a = 1, b = 3, c = a * b; a < 10; a++) {
...
}
```
## 值的比较
### 字符串比较
在比较字符串的大小时JavaScript 会使用 **Unicode 编码顺序** 顺序进行判定。
换言之,字符串是按字符(母)逐个进行比较的。
例如:
```javascript
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
```
字符串的比较算法非常简单:
1. 首先比较两个字符串的首位字符大小。
2. 如果一方字符较大(或较小),则该字符串大于(或小于)另一个字符串。算法结束。
3. 否则,如果两个字符串的首位字符相等,则继续取出两个字符串各自的后一位字符进行比较。
4. 重复上述步骤进行比较,直到比较完成某字符串的所有字符为止。
5. 如果两个字符串的字符同时用完,那么则判定它们相等,否则未结束(还有未比较的字符)的字符串更大。
### 不同类型间的比较
当对不同类型的值进行比较时,除了 `null``undefined`JavaScript 会首先将其转化为数字number再判定大小。
```js
alert( '2' > 1 ); // true字符串 '2' 会被转化为数字 2
alert( '01' == 1 ); // true字符串 '01' 会被转化为数字 1
alert( true == 1 ); // true
alert( false == 0 ); // true
```
### 严格相等
普通的相等性检查 `==` 存在一个问题,它不能区分出 `0``false`
```js
alert( 0 == false ); // true
```
也同样无法区分空字符串和 `false`
```javascript
alert( '' == false ); // true
```
**严格相等运算符 `===` 在进行比较时不会做任何的类型转换。**
```js
alert( 0 === false ); // false因为被比较值的数据类型不同
```
### null 与 undefined 比较
它们不相等,因为它们属于不同的类型。
```js
alert( null === undefined ); // false
```
JavaScript 存在一个特殊的规则,会判定它们相等。
```js
alert( null == undefined ); // true
```
`undefined``null` 在相等性检查 `==` 中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。
```js
alert( null > 0 ); // (1) false, null => 0
alert( null == 0 ); // (2) false, null => null
alert( null >= 0 ); // (3) true, null => 0
```
### undefined 与其他值比较
`undefined` 不应该被与其他值进行比较:
```javascript
alert( undefined > 0 ); // false
alert( undefined < 0 ); // false
alert( undefined == 0 ); // false
```
## 条件分支if 和 '?'
### 布尔转换
- 数字 `0`、空字符串 `""``null``undefined``NaN` 都会被转换成 `false`。因为它们被称为“假值falsy”。
- 其他值被转换为 `true`所以它们被称为“真值truthy”。
## 逻辑运算符
JavaScript 中有四个逻辑运算符:`||`(或),`&&`(与),`!`(非),`??`(空值合并运算符)。
### 或运算寻找第一个真值
一个或运算 `||` 的链,将返回第一个真值,如果不存在真值,就返回该链的最后一个值。
```js
alert( 1 || 0 ); // 11 是真值)
alert( null || 1 ); // 11 是第一个真值)
alert( null || 0 || 1 ); // 1第一个真值
alert( undefined || null || 0 ); // 0都是假值返回最后一个值
```
有趣的用法:
```js
let firstName = "";
let lastName = "";
let nickName = "SuperCoder";
alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
true || alert("not printed");
false || alert("printed");
```
### 与运算寻找第一个假值
```js
// 如果第一个操作数是真值,
// 与运算返回第二个操作数:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// 如果第一个操作数是假值,
// 与运算将直接返回它。第二个操作数会被忽略
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
alert( 1 && 2 && null && 3 ); // null
alert( 1 && 2 && 3 ); // 3最后一个值
```
### 与运算 `&&` 在或运算 `||` 之前进行
与运算 `&&` 的优先级比或运算 `||` 要高。
所以代码 `a && b || c && d``&&` 表达式加了括号完全一样:`(a && b) || (c && d)`
### !(非)
两个非运算 `!!` 有时候用来将某个值转化为布尔类型:
```javascript
alert( !!"non-empty string" ); // true
alert( !!null ); // false
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
```
也就是,第一个非运算将该值**转化为布尔类型并取反**,第二个非运算**再次取反**。最后我们就得到了一个任意值到布尔值的转化。
非运算符 `!` 的优先级在所有逻辑运算符里面最高,所以它总是在 `&&``||` 之前执行。
## 空值合并运算符 '??'
由于它对待 `null``undefined` 的方式类似,所以在本文中我们将使用一个特殊的术语对其进行表示。为简洁起见,当一个值既不是 `null` 也不是 `undefined`我们将其称为“已定义的defined”。
`a ?? b` 的结果是:
- 如果 `a` 是已定义的,则结果为 `a`
- 如果 `a` 不是已定义的,则结果为 `b`
我们可以使用我们已知的运算符重写 `result = a ?? b`,像这样:
```javascript
result = (a !== null && a !== undefined) ? a : b;
```
### 与 `||` 比较
它们之间重要的区别是:
- `||` 返回第一个 **真** 值。
- `??` 返回第一个 **已定义的** 值。
```js
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
```
## "switch" 语句
### 类型很关键
强调一下,这里的相等是严格相等。被比较的值必须是相同的类型才能进行匹配。
比如,我们来看下面的代码:
```js
let arg = prompt("Enter a value?")
switch (arg) {
case '0':
case '1':
alert( 'One or zero' );
break;
case '2':
alert( 'Two' );
break;
case 3:
alert( 'Never executes!' );
break;
default:
alert( 'An unknown value' )
}
```
1.`prompt` 对话框输入 `0``1`,第一个 `alert` 弹出。
2. 输入 `2`,第二个 `alert` 弹出。
3. 但是输入 `3`,因为 `prompt` 的结果是字符串类型的 `"3"`,不严格相等 `===` 于数字类型的 `3`,所以 `case 3` 不会执行!因此 `case 3` 部分是一段无效代码。所以会执行 `default` 分支。
## 函数
```js
function name(parameter1, parameter2, ... parameterN) {
...body...
}
name();
```
### 参数默认值
```js
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
```
```js
function showMessage(from, text = anotherFunction()) {
// anotherFunction() 仅在没有给定 text 时执行
// 其运行结果将成为 text 的值
}
```
### 后备的默认参数
有些时候,将参数默认值的设置放在函数执行(相较更后期)而不是函数声明时,也行得通。
我们可以通过将参数与 `undefined` 进行比较,来检查该参数是否在函数执行期间被传递进来:
```js
function showCount(count) {
// 如果 count 为 undefined 或 null则提示 "unknown"
alert(count ?? "unknown");
}
showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown
```
### 返回值
**空值的** `return` **或没有** `return` **的函数返回值为** `undefined`
```js
function doNothing() { /* 没有代码 */ }
function doNothing() {
return;
// return undefined;
}
alert( doNothing() === undefined ); // true
```
## 函数表达式