add: 扩展运算符

This commit is contained in:
qianguyihao 2020-08-23 23:32:42 +08:00
parent 72be5e546f
commit b78bdde343
8 changed files with 175 additions and 164 deletions

View File

@ -8,14 +8,16 @@ ES6 在**函数扩展**方面,新增了很多特性。例如:
- 参数结构赋值 - 参数结构赋值
- 扩展运算符 - 剩余参数
- rest 参数 - 扩展运算符
- this 绑定 - this 绑定
- 尾调用 - 尾调用
今天这篇文章我们讲一下箭头函数
## 箭头函数 ## 箭头函数
### 定义箭头函数的语法 ### 定义箭头函数的语法
@ -89,7 +91,7 @@ console.log(fn2(1)); //输出结果2
ES6 之前的普通函数中this 指向的是函数被调用的对象也就是说谁调用了函数this 就指向谁 ES6 之前的普通函数中this 指向的是函数被调用的对象也就是说谁调用了函数this 就指向谁
ES6 的箭头函数中**箭头函数本身不绑定 this**this 指向的是**箭头函数定义位置的 this**也就是说箭头函数在哪个位置定义的this 就跟这个位置的this指向相同 ES6 的箭头函数中**箭头函数本身不绑定 this**this 指向的是**箭头函数定义位置的 this**也就是说箭头函数在哪个位置定义的this 就跟这个位置的 this 指向相同
代码举例 代码举例
@ -118,8 +120,7 @@ obj
上面的代码中箭头函数是在 fn1()函数里面定义的所以第二个 this 第一个 this 指向的是**同一个位置**又因为在执行 `fn1.call(obj)`之后第一个 this 就指向了 obj所以第二个 this 也是指向 obj 上面的代码中箭头函数是在 fn1()函数里面定义的所以第二个 this 第一个 this 指向的是**同一个位置**又因为在执行 `fn1.call(obj)`之后第一个 this 就指向了 obj所以第二个 this 也是指向 obj
### 面试题箭头函数的 this 指向
### 面试题箭头函数的this指向
代码举例 代码举例
@ -137,7 +138,7 @@ obj.sayHello();
上方代码的打印结果是什么你可能很难想到 上方代码的打印结果是什么你可能很难想到
正确答案的打印结果是`许嵩`因为 `obj` 这个对象并不产生作用域 `sayHello()` 这个箭头函数实际仍然是定义在 window 当中的所以 这里的 this指向是 window 正确答案的打印结果是`许嵩`因为 `obj` 这个对象并不产生作用域 `sayHello()` 这个箭头函数实际仍然是定义在 window 当中的所以 这里的 this 指向是 window
## 参数默认值 ## 参数默认值
@ -205,156 +206,3 @@ fn('vae');
``` ```
此时打印结果是`vae smyh` 此时打印结果是`vae smyh`
## 扩展运算符剩余参数
注意区分
- 扩展运算符的格式为`...`
- rest 运算符的格式为`...变量名`
**剩余参数**允许我们将一个不确定数量的参数表示为一个**数组**
**传统写法**
ES5 在定义方法时参数要确定个数如下程序会报错
```javascript
function fn(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}
fn(1, 2, 3);
```
上方代码中因为方法的参数是三个但使用时是用到了四个参数所以会报错
![](http://img.smyhvae.com/20180304_1638.png)
**ES6写法**
ES6中我们有了扩展运算符就不用担心报错的问题了代码可以这样写
```javascript
function fn(...arg) {
//当不确定方法的参数时,可以使用扩展运算符
console.log(arg[0]);
console.log(arg[1]);
console.log(arg[2]);
console.log(arg[3]);
}
fn(1, 2, 3); //方法的定义中了四个参数但调用函数时只使用了三个参数ES6 中并不会报错。
```
![](http://img.smyhvae.com/20180304_1650.png)
上方代码中注意arg 参数之后不能再加别的参数否则编译报错
还可以这样写
```js
function fn1(first, ...args) {
console.log(first); // 10
console.log(args); // 数组:[20, 30]
}
fn1(10, 20, 30);
```
### 剩余参数的举例
**举例1**将参数求和
代码举例
```js
function fn1(...args) {
let sum = 0;
args.forEach(item => sum += item);
return sum;
}
console.log(fn1(10, 20, 30));
```
打印结果60
**举例2**数组赋值的问题
我们来分析一段代码将数组 arr1 赋值给 arr2
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = arr1; // 将 arr1 赋值给 arr2其实是让 arr2 指向 arr1 的内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果
![](http://img.smyhvae.com/20180304_1950.png)
上方代码中我们往往 arr2 里添加了`你懂的`却发现arr1 里也有这个内容原因是`let arr2 = arr1;`其实是让 arr2 指向 arr1 的地址也就是说二者指向的是同一个内存地址
如果不想让 arr1 arr2 指向同一个内存地址我们可以借助扩展运算符来做
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = [...arr1]; //arr2 会重新开辟内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果
![](http://img.smyhvae.com/20180304_1951.png)
我们明白了这个例子就可以避免开发中的很多业务逻辑上的 bug
## `rest` 运算符
`rest` 在英文中指的是**剩余部分**不是指休息我们来举个例子理解剩余部分的含义
```javascript
function fn(first, second, ...arg) {
console.log(arg.length);
}
fn(0, 1, 2, 3, 4, 5, 6); // 调用函数后,输出结果为 5
```
上方代码的输出结果为 5 调用`fn()`里面有七个参数`arg`指的是剩下的部分因为除去了`first``second`
从上方例子中可以看出`rest`运算符适用于知道前面的一部分参数的数量但对于后面剩余的参数数量未知的情况
## 模块化
**模块化的意义**
比如说当我需要用到 jQuery 库时我会把 jQuery.js 文件引入到我自己代码的最前面当我需要用到 vue 框架时我会把 vue.js 文件引入到我自己代码的最前面
可是如果有 20 个这样的文件就会产生 20 http 请求这种做法的性能肯定是不能接受的
如果把 20 个文件直接写在一个文件里肯定是不方便**维护**可如果写成 20 个文件 20 个文件又不好排序这就是一个很矛盾的事情于是模块化就诞生了
**模块化历程**commonJSAMD 规范RequireJSCMD 规范SeaJSimport & export
**export**
静态化必须在顶部不能使用条件语句自动采用严格模式静态化有利于性能以及代码的稳定性

View File

@ -0,0 +1,160 @@
## 剩余参数
**剩余参数**允许我们将不确定数量的**剩余的元素**放到一个**数组**
比如说当函数的实参个数大于形参个数时我们可以将剩余的实参放到一个数组中
**传统写法**
ES5 在定义方法时参数要确定个数如下程序会报错
```javascript
function fn(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}
fn(1, 2, 3);
```
上方代码中因为方法的参数是三个但使用时是用到了四个参数所以会报错
![](http://img.smyhvae.com/20180304_1638.png)
**ES6 写法**
ES6 我们有了剩余参数就不用担心报错的问题了代码可以这样写
```javascript
const fn = (...args) => {
//当不确定方法的参数时,可以使用剩余参数
console.log(args[0]);
console.log(args[1]);
console.log(args[2]);
console.log(args[3]);
};
fn(1, 2);
fn(1, 2, 3); //方法的定义中了四个参数但调用函数时只使用了三个参数ES6 中并不会报错。
```
打印结果
```
1
2
undefined
undefined
1
2
3
undefined
```
上方代码中注意args 参数之后不能再加别的参数否则编译报错
下面这段代码也是利用到了剩余参数
```js
function fn1(first, ...args) {
console.log(first); // 10
console.log(args); // 数组:[20, 30]
}
fn1(10, 20, 30);
```
### 剩余参数的举例参数求和
代码举例
```js
const sum = (...args) => {
let total = 0;
args.forEach(item => total += item); // 注意 forEach里面的代码写得 很精简
return total;
};
console.log(sum(10, 20, 30));
```
打印结果60
### 剩余参数和解构赋值配合使用
代码举例
```js
const students = ['张三', '李四', '王五'];
let [s1, ...s2] = students;
console.log(s1); // '张三'
console.log(s2); // ['李四', '王五']
```
## 扩展运算符展开语法
扩展运算符和剩余参数是相反的
剩余参数是将剩余的元素放到一个数组中而扩展运算符是将数组或者对象拆分成逗号分隔的参数序列
代码举例
```js
const arr = [10, 20, 30];
...arr // 10, 20, 30 注意,这一行是伪代码
console.log(...arr); // 10 20 30
console.log(10, 20, 30); // 10 20 30
```
上面的代码要仔细看
`arr`是一个数组`...arr`则表示`10, 20, 30`这样的序列
我们把`...arr` 打印出来发现打印结果竟然是 `10 20 30`为啥逗号不见了呢因为逗号被当作了 console.log 的参数分隔符如果你不信可以直接打印 `console.log(10, 20, 30)` 看看
**举例**数组赋值的问题
我们来分析一段代码将数组 arr1 赋值给 arr2
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = arr1; // 将 arr1 赋值给 arr2其实是让 arr2 指向 arr1 的内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果
![](http://img.smyhvae.com/20180304_1950.png)
上方代码中我们往往 arr2 里添加了`你懂的`却发现arr1 里也有这个内容原因是`let arr2 = arr1;`其实是让 arr2 指向 arr1 的地址也就是说二者指向的是同一个内存地址
如果不想让 arr1 arr2 指向同一个内存地址我们可以借助扩展运算符来做
```javascript
let arr1 = ['www', 'smyhvae', 'com'];
let arr2 = [...arr1]; //arr2 会重新开辟内存地址
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
console.log('---------------------');
arr2.push('你懂得'); //往arr2 里添加一部分内容
console.log('arr1:' + arr1);
console.log('arr2:' + arr2);
```
运行结果
![](http://img.smyhvae.com/20180304_1951.png)
我们明白了这个例子就可以避免开发中的很多业务逻辑上的 bug

View File

@ -24,6 +24,9 @@
一次编写多次使用才是提高效率的核心 一次编写多次使用才是提高效率的核心
## 模块化的理解 ## 模块化的理解
### 什么是模块化 ### 什么是模块化
@ -120,7 +123,7 @@ CommonJS 就是一套约定标准,不是技术。用于约定我们的代码
PS面试时经常会问AMD CMD 的区别 PS面试时经常会问AMD CMD 的区别
另外还有ES6规范 另外还有ES6规范import & export
这篇文章我们来讲一下`CommonJS`它是 Node.js 使用的模块化规范 这篇文章我们来讲一下`CommonJS`它是 Node.js 使用的模块化规范

View File

@ -340,17 +340,17 @@ export default class PicturesWall extends PureComponent {
Demo在线演示 Demo在线演示
- <https://stackoverflow.com/questions/58128062/using-customrequest-in-ant-design-file-upload> - https://stackoverflow.com/questions/58128062/using-customrequest-in-ant-design-file-upload
- <https://stackblitz.com/edit/so-58128062-upload-progress> - <https://stackblitz.com/edit/so-58128062-upload-progress>
fileList 格式在线演示 fileList 格式在线演示
- <https://stackoverflow.com/questions/51514757/action-function-is-required-with-antd-upload-control-but-i-dont-need-it> - https://stackoverflow.com/questions/51514757/action-function-is-required-with-antd-upload-control-but-i-dont-need-it
- <https://codesandbox.io/s/rl7ooo544q> - https://codesandbox.io/s/rl7ooo544q
ant design Upload组件的使用总结https://www.jianshu.com/p/0aa4612af987 ant design Upload组件的使用总结https://www.jianshu.com/p/0aa4612af987
antd上传功能的CustomRequest<https://mlog.club/article/3832743> antd上传功能的CustomRequesthttps://mlog.club/article/3832743

View File