add: 扩展运算符
This commit is contained in:
parent
72be5e546f
commit
b78bdde343
@ -8,14 +8,16 @@ ES6 在**函数扩展**方面,新增了很多特性。例如:
|
|||||||
|
|
||||||
- 参数结构赋值
|
- 参数结构赋值
|
||||||
|
|
||||||
- 扩展运算符
|
- 剩余参数
|
||||||
|
|
||||||
- rest 参数
|
- 扩展运算符
|
||||||
|
|
||||||
- this 绑定
|
- this 绑定
|
||||||
|
|
||||||
- 尾调用
|
- 尾调用
|
||||||
|
|
||||||
|
今天这篇文章,我们讲一下箭头函数。
|
||||||
|
|
||||||
## 箭头函数
|
## 箭头函数
|
||||||
|
|
||||||
### 定义箭头函数的语法
|
### 定义箭头函数的语法
|
||||||
@ -118,7 +120,6 @@ obj
|
|||||||
|
|
||||||
上面的代码中,箭头函数是在 fn1()函数里面定义的,所以第二个 this 跟 第一个 this 指向的是**同一个位置**。又因为,在执行 `fn1.call(obj)`之后,第一个 this 就指向了 obj,所以第二个 this 也是指向 了 obj。
|
上面的代码中,箭头函数是在 fn1()函数里面定义的,所以第二个 this 跟 第一个 this 指向的是**同一个位置**。又因为,在执行 `fn1.call(obj)`之后,第一个 this 就指向了 obj,所以第二个 this 也是指向 了 obj。
|
||||||
|
|
||||||
|
|
||||||
### 面试题:箭头函数的 this 指向
|
### 面试题:箭头函数的 this 指向
|
||||||
|
|
||||||
代码举例:
|
代码举例:
|
||||||
@ -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 个文件又不好排序。这就是一个很矛盾的事情,于是,模块化就诞生了。
|
|
||||||
|
|
||||||
**模块化历程**:commonJS、AMD 规范(RequireJS)、CMD 规范(SeaJS);import & export
|
|
||||||
|
|
||||||
**export:**
|
|
||||||
|
|
||||||
静态化:必须在顶部,不能使用条件语句,自动采用严格模式。(静态化有利于性能以及代码的稳定性)
|
|
||||||
|
160
05-JavaScript之ES6语法/07-剩余参数和扩展运算符.md
Normal file
160
05-JavaScript之ES6语法/07-剩余参数和扩展运算符.md
Normal 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。
|
@ -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 使用的模块化规范。
|
||||||
|
|
||||||
|
@ -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上传功能的CustomRequest:https://mlog.club/article/3832743
|
||||||
|
|
||||||
|
0
16-推荐链接/2020-推荐文章.md
Normal file
0
16-推荐链接/2020-推荐文章.md
Normal file
Loading…
Reference in New Issue
Block a user