Compare commits

..

1 Commits

Author SHA1 Message Date
jianghd001
ed30c70bab
Merge 0ee5b1349a into ed1162b0f7 2024-07-30 16:41:31 -07:00
3 changed files with 40 additions and 149 deletions

View File

@ -22,7 +22,7 @@ title: 09-数据类型转换
- 转换为布尔型 - 转换为布尔型
我需要专门把某个数据类型转换成 null 或者 undefined 吗?因为这样做没有意义。 你会专门把某个数据类型转换成 null 或者 undefined 吗?不会,因为这样做没有意义。
## 变量的类型转换的分类 ## 变量的类型转换的分类
@ -245,12 +245,12 @@ const result = Number(变量/常量);
使用 Number() 函数转为数字的规则如下: 使用 Number() 函数转为数字的规则如下:
| 原始值 | 转换后的值 | | 原始值 | 转换后的值 |
| --------- | ------------------------------------------------------------ | | ------------------- | ------------------------------------------------------------ |
| 字符串 | 1字符串去掉首尾空格后剩余字符串的内容如果是纯数字则直接将其转换为数字。<br/>2字符串去掉首尾空格后剩余字符串包的内容只要含了其他非数字的内容`小数点`按数字来算),则转换为 NaN。怎么理解这里的 **NaN** 呢?可以这样理解,使用 Number() 函数之后,**如果无法转换为数字,就会转换为 NaN**。<br />3如果字符串是一个**空串**或者是一个**全是空格**的字符串,则转换为 0。<br/> | | 字符串 | 1字符串去掉首尾空格后剩余字符串的内容如果是纯数字则直接将其转换为数字。<br/>2)如果字符串是一个**空串**或者是一个**全是空格**的字符串,则转换为 0。<br/>3)字符串去掉首尾空格后,剩余字符串包的内容只要含了其他非数字的内容(`小数点`按数字来算),则转换为 NaN。怎么理解这里的 **NaN** 呢?可以这样理解,使用 Number() 函数之后,**如果无法转换为数字,就会转换为 NaN**。 |
| 布尔值 | true 转成 1false 转成 0 | | 布尔值true、false | true 转成 1false 转成 0 |
| undefined | NaN | | undefined | NaN |
| null | 0 | | null | 0 |
### 2、隐式类型转换——运算符加号 `+` ### 2、隐式类型转换——运算符加号 `+`
@ -488,7 +488,7 @@ parseFloat() 的几个特性,可以参照 parseInt()。
其他的数据类型都可以转换为 Boolean 类型。无论是隐式转换,还是显示转换,转换结果都是一样的。有下面几种情况: 其他的数据类型都可以转换为 Boolean 类型。无论是隐式转换,还是显示转换,转换结果都是一样的。有下面几种情况:
转换为 Boolean 类型的规则如下: 使用 Number() 函数转为数字的规则如下:
| 原始值 | 转换后的值 | | 原始值 | 转换后的值 |
| --------- | ------------------------------------------------------------ | | --------- | ------------------------------------------------------------ |
@ -502,7 +502,7 @@ parseFloat() 的几个特性,可以参照 parseInt()。
**重中之重来了:** **重中之重来了:**
转换为 Boolean 的上面这几种情况,**极其重要**项目开发中会频繁用到。比如说,我们在项目开发中,经常需要对一些**非布尔值**做**逻辑判断或者逻辑运算**,符合条件后,才做下一步的事情。这个逻辑判断就是依据上面的四种情况。 转换为 Boolean 的上面这几种情况,**极其重要**,开发中会频繁用到。比如说,我们在项目开发中,经常需要对一些**非布尔值**做**逻辑判断或者逻辑运算**,符合条件后,才做下一步的事情。这个逻辑判断就是依据上面的四种情况。
举例:(接口返回的内容不为空,前端才做进一步的事情) 举例:(接口返回的内容不为空,前端才做进一步的事情)

View File

@ -4,12 +4,12 @@ title: 10-运算符
<ArticleTopAd></ArticleTopAd> <ArticleTopAd></ArticleTopAd>
我们在前面讲过变量,本文讲一下**运算符**和表达式。
## 运算符的定义和分类 ## 运算符的定义和分类
### 运算符的定义 ### 运算符的定义
运算符和表达式形影不离,先来介绍一下概念。
**运算符**:也叫操作符,是一种符号。通过运算符可以对一个或多个值进行运算,并获取运算结果。 **运算符**:也叫操作符,是一种符号。通过运算符可以对一个或多个值进行运算,并获取运算结果。
**表达式**:数字、运算符、变量的组合(组成的式子)。 **表达式**:数字、运算符、变量的组合(组成的式子)。
@ -24,7 +24,7 @@ title: 10-运算符
例如:在加法运算中,运算元就是加法操作符两侧的值或变量。在逻辑运算中,运算元是指用于计算逻辑表达式的操作数。 例如:在加法运算中,运算元就是加法操作符两侧的值或变量。在逻辑运算中,运算元是指用于计算逻辑表达式的操作数。
如果一个运算符(比如加法运算符)拥有两个运算元,那么它是二元运算符。一元运算符、三元运算符的概念同理。 如果一个运算符(比如加法运算符)拥有两个运算元,那么它是二元运算符。
### 运算符的分类 ### 运算符的分类
@ -48,14 +48,13 @@ JS 中的运算符,分类如下:
常见的算数运算符有以下几种: 常见的算数运算符有以下几种:
| 运算符 | 描述 | | 运算符 | 描述 |
| :----- | :---------------------: | | :----- | :--------------------: |
| + | 加、字符串连接 | | + | 加、字符串连接 |
| - | 减 | | - | 减 |
| \* | 乘 | | \* | 乘 |
| / | 除 | | / | 除 |
| % | 获取余数(取余/取模) | | % | 获取余数(取余、取模) |
| ** | 幂运算,是 ES7 新增特性 |
**求余的举例** **求余的举例**
@ -98,7 +97,7 @@ var a = 1 + ((2 * 3) % 4) / 3;
原式 = 1 + 6 % 4 / 3 = 1 + 2 / 3 = 1.66666666666666 原式 = 1 + 6 % 4 / 3 = 1 + 2 / 3 = 1.66666666666666
### 取余(取模)运算 ### 取模(取余)运算
格式: 格式:
@ -106,8 +105,6 @@ var a = 1 + ((2 * 3) % 4) / 3;
余数 = m % n; 余数 = m % n;
``` ```
`%`符号在这里并不是用来做百分号的计算,和百分号计算没有关系。
计算结果注意: 计算结果注意:
- 取余运算结果的正负性,取决于 m而不是 n。比如`10 % -3`的运算结果是 1。`-10 % 3`的运算结果是-1。 - 取余运算结果的正负性,取决于 m而不是 n。比如`10 % -3`的运算结果是 1。`-10 % 3`的运算结果是-1。
@ -119,23 +116,6 @@ var a = 1 + ((2 * 3) % 4) / 3;
- 如果 m>=n那就正常取余。 - 如果 m>=n那就正常取余。
- 如果 m<n那结果就是 m - 如果 m<n那结果就是 m
### 幂运算
`**`这个符号在JS中是幂运算符是ES7中新增的特性。比如2的3次方可以表示为 `2**3`
除了`**`运 算符之外JavaScript 还提供了`Math.pow()方法,也可以进行幂运算。
下面两行代码是等价的2的3次方
```
2**3;
Math.pow(2, 3);
```
此外,需要注意,`** `运算符的优先级高于乘法和除法运算符。
### 浮点数运算的精度问题 ### 浮点数运算的精度问题
浮点数值的最高精度是 17 位小数,但在进行算术计算时,会丢失精度,导致计算不够准确。比如: 浮点数值的最高精度是 17 位小数,但在进行算术计算时,会丢失精度,导致计算不够准确。比如:
@ -148,12 +128,6 @@ console.log(0.07 * 100); // 运算结果不是 7而是 7.000000000000001
因此,**不要直接判断两个浮点数是否相等**。前面的文章《JavaScript 基础基本数据类型Number》有详细介绍。 因此,**不要直接判断两个浮点数是否相等**。前面的文章《JavaScript 基础基本数据类型Number》有详细介绍。
实际项目中,涉及数字计算的这部分,比较麻烦,且非常严谨;尤其是交易、金钱相关的业务,则一定不能出错。
如果你直接把两个数字进行加减乘除,很容易丢失精度,导致计算不准确。实战中,往往需要把计算相关的代码封装成公共方法,提供给业务侧调用。
我们也可以在开源网站找到一些已经封装好的工具类,比较知名的是 [big.js](https://github.com/MikeMcl/big.js)。
## 自增和自减运算符 ## 自增和自减运算符
### 自增运算符 `++` ### 自增运算符 `++`
@ -547,51 +521,31 @@ if (result.retCode == 0) {
### 赋值运算符包括哪些 ### 赋值运算符包括哪些
| 运算符 | 运算规则 | 举例 | - `=` 直接赋值。比如 `var a = 5`。意思是,把 5 这个值,往 a 里面存一份。简称:把 5 赋值给 a。
| ------ | ------------ | --------------------------- |
| = | 直接赋值 | let a = 5 |
| += | 加后赋值 | a += 5 等价于 a = a + 5 |
| -= | 减后赋值 | a -= 5 等价于 a = a - 5 |
| *= | 乘后赋值 | a *= 5 等价于 a = a * 5 |
| /= | 除后赋值 | a /= 5 等价于 a = a / 5 |
| %= | 取余数后赋值 | a %= 5 等价于 a = a % 5 |
| **= | 幂运算后赋值 | `a **= 5` 等价于 `a = a**5` |
1、直接赋值 - `+=`:比如 a += 5 等价于 a = a + 5。
`=` 运算符是直接赋值,很容易理解。比如 `let a = 5`。意思是把 5 这个值,往 a 里面存一份。简称:把 5 赋值给 a - `-=`:比如 a -= 5 等价于 a = a - 5。
2、优先级算数运算符的优先级高于赋值运算符。举例 - `*=`:比如 a _ = 5 等价于 a = a -5。
- `/=`:比如 a /= 5 等价于 a = a / 5。
- `%=`:比如 a %= 5 等价于 a = a % 5。
### 注意事项
1算数运算符的优先级高于赋值运算符。举例
```js ```js
const result = 1 + 2; // 先计算 1 + 2再把计算结果赋值给 result。因为算数运算符的优先级高于赋值运算符。 const result = 1 + 2; // 先计算 1 + 2再把计算结果赋值给 result。因为算数运算符的优先级高于赋值运算符。
``` ```
3、**原地修改**Modify-in-place 2赋值运算符的结合性是右结合性从右至左的顺序计算。举例
“原地修改”是数据结构中比较常见的概念。定义是:直接在数据原有的存储位置上进行修改,而不是创建一个新的副本(即新的存储空间)来存储修改后的结果。这种方式可以减少内存的使用,因为不需要额外的存储空间来保存修改后的数据。
通俗理解:对一个变量进行运算,并将新的运算结果存储在原有变量中。
上面列出的赋值运算符中,`=`符号是直接赋值,其他的赋值运算都是属于原地修改。
### 链式赋值chaining assignments
举例:
```js ```js
const a = b = c = 2; const a1, a2;
``` a1 = a2 = 3; // 先将 3 复制给 a2再将 a2 的值赋值给 a1
解释:把 a、b、c 都赋值为2。
注意:链式赋值的结合性是右结合性(从右至左的顺序进行计算)。举例:
```js
const a, b;
a = b = 3; // 先将 3 复制给 b再将 b 的值赋值给 a
``` ```

View File

@ -1476,9 +1476,7 @@ console.log(arr2);
## filter() ## filter()
### 语法 语法:
```js ```js
const newArr = arr.filter((currentItem, currentIndex, currentArray) => { const newArr = arr.filter((currentItem, currentIndex, currentArray) => {
@ -1490,8 +1488,6 @@ const newArr = arr.filter((currentItem, currentIndex, currentArray) => {
作用:对数组进行过滤。 作用:对数组进行过滤。
### 举例
**举例 1**:找出数组 arr1 中大于 4 的元素,返回一个新的数组。代码如下: **举例 1**:找出数组 arr1 中大于 4 的元素,返回一个新的数组。代码如下:
```javascript ```javascript
@ -1525,12 +1521,12 @@ console.log(JSON.stringify(arr2)); // 打印结果:[6,5,6]
```javascript ```javascript
const arr1 = [ const arr1 = [
{ name: '许嵩', type: '一线' }, { name: '许嵩', type: '一线' },
{ name: '周杰伦', type: '退居二线' }, { name: '周杰伦', type: '退居二线' },
{ name: '邓紫棋', type: '一线' }, { name: '邓紫棋', type: '一线' },
]; ];
const arr2 = arr1.filter(item => item.type == '一线'); // 筛选出一线歌手 const arr2 = arr1.filter((item) => item.type == '一线'); // 筛选出一线歌手
console.log(JSON.stringify(arr2)); console.log(JSON.stringify(arr2));
``` ```
@ -1544,65 +1540,6 @@ console.log(JSON.stringify(arr2));
]; ];
``` ```
### 两端代码对比
仔细看看下面这两段代码,有什么区别。数组 arr2的打印结果是不一样的。
第一段代码:
```js
const arr1 = [
{
name: 'a',
num: 1,
},
{
name: 'b',
num: 2,
},
];
const arr2 = [];
const arr3 = dataList.filter(item => {
return item.num === 1;
arr2.push(item);
});
console.log(arr2);
```
第二段代码:
```js
const arr1 = [
{
name: 'a',
num: 1,
},
{
name: 'b',
num: 2,
},
];
const arr2 = [];
const arr3 = dataList.filter(item => {
if (item.num === 1) return item;
arr2.push(item);
});
console.log('smyhvae arr2:', arr2);
```
分析:
- 第一段代码的打印结果是 空数组 `[]`。因为`return` 语句位于回调函数的第一行,所以一旦执行就直接返回,导致后面的 `arr2.push(item);` 永远不会被执行,因此 `arr2` 始终为空。
- 第二段代码的打印结果是` [{ name: 'b', num: 2 }]`。由于 `return` 语句位于 `if` 语句内部,只有在特定条件下(`item.num === 1`)才会终止回调函数,否则 `arr2.push(item);` 仍然会被执行,因此 `arr2` 中会有值。
## reduce() ## reduce()
### reduce() 语法 ### reduce() 语法