学习

https://es6.ruanyifeng.com/

https://www.bookstack.cn/read/es6/readme.md

循环遍历

https://mp.weixin.qq.com/s/PIhqed9uapE_Tgx761GExQ

图片

… 操作符

...操作符有两种意义:rest(剩余语法,rest 参数) 和 spread(展开语法,展开数组 / 对象),作为函数、数组、对象的扩展运算符。

从某种意义上说,剩余语法与展开语法是相反的
剩余语法将多个元素收集起来并“凝聚”为单个元素,而展开语法则是将数组、对象、字符串展开为其中的各个元素

rest 剩余语法

  • …变量名
  • 作为形参或等号左侧的变量,为接收值的一方
  • 变量接收到的值为数组或对象
1
2
3
4
5
6
7
8
//函数参数
function(a, b, ...theArgs) {
// ...
}

//解构赋值
let [first,...rest]=[1,2,3,4,5];
let { x, ...y } = { x: 1, a: 2, b: 3 };

Spread 展开语法

  • …变量名 或者 …常量
  • 作为实参或等号右侧的内容,为提供数据的一方

数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
console.log(1,...arr)
arr1.push(...arr) //注意:push 方法的参数不能是数组

//复制数组
const itemsCopy = [...items]; //浅拷贝

//合并数组
arr = [4, ...list]

Math.max(...[14,3,7])
// 等同于
Math.max(14, 3, 77);

let arr = [...map.keys()];

对象

1
2
3
4
5
6
7
8
let z = { a: 3, b: 4 };
let n = { ...z }; //拷贝

let aClone = Object.assign({}, a);

//合并对象
let ab = { ...a, ...b }; // 等同于,
let ab = Object.assign({}, a, b);

字符串

1
let a = [...'hello']    // [ "h", "e", "l", "l", "o" ]

解构

  • 从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)

  • 本质上,这种写法属于 “模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值

  • 如果解构不成功,变量的值就等于 undefined

字符串

字符串被转换成了一个类似数组的对象

1
2
3
4
5
6
7
8
9
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

let {length : len} = 'hello';
len // 5

数组

如果等号的右边不是数组,则会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let [a, b, c] = [1, 2, 3];

let [foo, [[bar], baz]] = [1, [[2], 3]];

let [a, b, d] = [1, [2, 3], 4];
b: [2, 3]

let [ , , third] = ["foo", "bar", "baz"];

let [head, ...tail] = [1, 2, 3, 4];

//不完全解构
let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

//解构赋值允许指定默认值
let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

对象

  • 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
  • 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者
  • 对象的解构也可以指定默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello

//如果变量名与属性名不一致
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

//实质
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };

var {x, y = 5} = {x: 1};
x // 1
y // 5

函数参数

1
2
3
4
5
6
7
8
9
10
11
12
13
function add([x, y]){
return x + y;
}
add([1, 2]); // 3

function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});


function myFunction(x = 1, y = 2, z = 3) {
console.log(x, y, z);
}
myFunction(6,7); // Outputs 6 7 3

用途

  1. 交换变量的值

  2. 从函数返回多个值

  3. 函数参数的定义

  4. 提取 JSON 数据

  5. 遍历 Map 结构。for … of

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for (let [key, value] of map) {
    console.log(key + " is " + value);
    }

    // 获取键名
    for (let [key] of map) {
    // ...
    }

    // 获取键值
    for (let [,value] of map) {
    // ...
    }

数组

Array - JavaScript | MDN (mozilla.org)

是否包含某元素 includes

1
2
3
let fileSuffix = 'png'
['png','jpg','jpeg','gif','bmp','wmf','mpt','svg','tif','dib','dif'].includes(fileSuffix)
// true

遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//遍历数组,打印元素
for (let elem of ['a', 'b']) {
console.log(elem);
}
// 'a'
// 'b'

//遍历数组,打印索引
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1


//遍历数组,打印索引和元素
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"

//遍历 json 数组
let lcTypes = [];
for (const dict of dictOptions) {
lcTypes.push({text:dict.text,value:dict.value})
}

如果不使用 for...of 循环,可以手动调用遍历器对象的 next 方法,进行遍历。

1
2
3
4
5
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

过滤 filter

1
2
3
4
let a = [1,2,3,4,5,6]
let b = a.filter(e=>e>3)
b
(3) [4, 5, 6]

创建一个新数组-map

1
2
3
4
5
6
7
const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

数组截取 - slice

slice() 方法返回一个新的数组对象,这一对象是一个由 startend 决定的原数组的浅拷贝(包括 start,不包括 end),其中 startend 代表了数组元素的索引。原始数组不会被改变

如果是负值,则表示从数组最后一个元素开始倒数 -1、-2、…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice(1, 5));
// Expected output: Array ["bison", "camel", "duck", "elephant"]

console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]

console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]

数组开头增加元素

unshift() 方法将指定元素添加到数组的开头,并返回数组的新长度

1
2
3
4
5
6
7
const array1 = [1, 2, 3];

console.log(array1.unshift(4, 5));
// Expected output: 5

console.log(array1);
// Expected output: Array [4, 5, 1, 2, 3]

从数组中删除第一个元素

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度

1
2
3
4
5
6
7
8
9
const array1 = [1, 2, 3];

const firstElement = array1.shift();

console.log(array1);
// Expected output: Array [2, 3]

console.log(firstElement);
// Expected output: 1

json 对象

object 对象 key 使用变量命名

1
2
let key = "name"
let obj = { [key]: "Bob" } //{name: "Bob"}

Object.assign(target, source1, source2)

1
2
3
4
5
6
var obj = { foo: 'bar', baz: 42 };
Object.assign(obj, {name: "hello"})
console.log(obj); // { foo: 'bar', baz: 42, name: "hello" }

//等价于
obj = {...obj, name: "hello"}

遍历对象【重要】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var obj = { foo: 'bar', baz: 42 };
for( let key in obj) {
console.log(key); // foo baz
console.log(obj[key]); // bar 42
}

var obj = { foo: 'bar', baz: 42 };
for (let key of Object.keys(obj)) {
console.log(key); // foo baz
}

const obj = { foo: 'bar', baz: 42 };
for (let value of Object.values(obj)) {
console.log(value); // bar 42
}

const obj = { foo: 'bar', baz: 42 };
for (let [key, value] of Object.entries(obj)) {
console.log([key, value]); // ["foo", "bar"] ["baz", 42]
}

Object

判断两个对象是否相等。如果是引用类型,判断是否是同一个对象

1
Object.is(a,b)

async 和 await

async 和 await 大多数情况是同时出现的,async 放在 function 前面 是表示这个是一个异步函数,同时,这个函数返回的就是一个 promise 对象

await 意思就是 等待,等待注册的 then 函数体异步返回,在没有收到返回值的情况下,他是不会继续向下执行的

1
2
3
4
5
6
7
8
9
10
11
12
(async function (){
async function f() {
return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

let a = await f();
console.log(a)
// "hello world"
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async postPaper() {
let paperId = this.paperId
let res = await this.postFormAction(this.url.submitPaper, { paperId })
if (res.success) {
this.$message.success(res.message)
} else {
this.$message.error(res.message)
}
//触发自定义事件 刷新列表页面
this.$emit('paper');
this.visiblelock = false
}

// 调用:方式一
await postPaper()
console.log("后续操作")

// 调用:方式二
this.submitAnswer().then(()=>{
console.log("后续操作")
});

export default 与 export

1
2
3
4
5
// test.js
export default {
name: 'zs',
age: 20
}
1
2
3
4
5
6
// test.js
var info = {
name: 'zs',
age: 20
}
export default inf

在 main.js 中接收,test.js 使用 export default 向外暴露的成员

1
2
import person from './test.js'
console.log(person);

注意:

1、export default 向外暴露的成员,可以使用任意变量来接收

2、在一个模块中,export default 只允许向外暴露一次

3、在一个模块中,可以同时使用 export default 和 export 向外暴露成员

1
2
3
4
5
6
7
8
9
10
// test.js
var info = {
name: 'zs',
age: 20
}
export default info

export var title = '小星星'

export var content = '哈哈哈'

4、使用 export 向外暴露的成员,只能使用 { } 的形式来接收,这种形式,叫做【按需导出】

5、export 可以向外暴露多个成员,同时,如果某些成员,在 import 导入时,不需要,可以不在 { } 中定义

6、使用 export 导出的成员,必须严格按照导出时候的名称,来使用 { } 按需接收

7、使用 export 导出的成员,如果想换个变量名称接收,可以使用 as 来起别名

1
2
3
4
//在 main.js 中接收,test.js 使用 export default 和 export 向外暴露的成员
import person, {title, content as content1} from './test.js'
console.log(person);
console.log(title + '=======' + content1);