ES6学习笔记-2

继续上一篇ES6学习笔记-1(掘金)

1.Promise-then方法

上一篇已经介绍过Promise的基本概念和用法,现在来说说then

当我们创建了一个Promise后,可以调用then方法来对Promise执行后的状态分别指定对应的方法进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
 // 创建promise对象
const p = new Promise(function (resolve, reject){
setTimeout(()=>{
resolve('用户数据')
},1000);
});
//对成功状态和失败状态作处理
p.then(value => {
console.log(value)
},reason => {
console.error(reason)
})

2.then的链式调用实例

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
34
35
36
// 引入fs模块
const fs = require('fs')
// fs.readFile('./data/计算机网络.md',(err,data1)=>{
// fs.readFile('./data/软件测试.md',(err, data2) => {
// fs.readFile('./data/黑盒测试.md',(err,data3)=>{
// let result = data1+data2+data3;
// console.log(result)
// })
// })
// })



//Promise实现
//then方法的链式调用
let p = new Promise(function (resolve, reject){
fs.readFile('./data/计算机网络.md',(err,data)=>{
resolve(data);
})
}).then(function (value) {
return new Promise((resolve,reject)=>{
fs.readFile('./data/软件测试.md',(err,data)=>{
resolve([value,data])
});
})
}).then(value => {
return new Promise(((resolve, reject) => {
fs.readFile('./data/黑盒测试.md',(err,data)=>{
value.push(data);
resolve(value)
})
}))
}).then(value => {
console.log(value.join('\r\n'));
})

3.Set和Map

3.1 Set()

在ES6中提供了新的数据结构Set集合,它类似于数组,但成员的值是唯一的;集合实现了iterator接口,所以可以使用扩展运算符…**和for…of**循环遍历。

Set集合的属性和方法:

  1. size:返回集合的元素个数
  2. add:增加一个新元素,并返回当前集合
  3. delete:删除元素,返回boolean值
  4. has:检测集合中是否包含某个元素,返回boolean值

实例1:

1
2
3
4
5
6
7
8
9
10
11
12
// 1.先声明一个set集合
let s1 = new Set();
let s2 = new Set([1,2,3,1,2,1,2,3,4,5,64,3])
console.log(s1,typeof s1)
console.log(s2) //返回[1,2,3,4,5,64],会自动去除重复的元素

// size 元素的个数,与数组不一样,数组是length
console.log('size = '+s2.size) //输出6
// for...of
for (let i of s2){
console.log(i)
}

实例2:

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
34
35
36
let arr1= [1,2,3,4,5,4,3,2,1]
//1.数组去重,利用Set和扩展运算符...可以实现
let s1 = [...new Set(arr1)];
console.log(s1)

//2.交集
let arr2 = [4,5,6,4,5,9];
// let result = [...new Set(arr1)].filter(item=>{
// let s2 = new Set(arr2); //4,5,6
// if (s2.has(item)){
// return true
// }else {
// return false
// }
// })
//简写
let result = [...new Set(arr1)].filter(item=> (new Set(arr2).has(item)))
console.log(result)

//3.并集
let union = new Set([...arr1,...arr2])

console.log(union)

//4.差集
// let diff = [...new Set(arr1)].filter(item=>{
// let s2 = new Set(arr2); //4,5,6
// if (!s2.has(item)){
// return true
// }else {
// return false
// }
// })
//简写
let diff = [...new Set(arr1)].filter(item=> !(new Set(arr2).has(item)))
console.log(diff)
3.2 Map()

在ES6中提供了新的数据结构Map集合,它类似于对象,是键值对的集合;此外,Map的key值可以是任何数据类型,Map集合也实现了iterator接口,所以可以使用扩展运算符…**和for…of**循环遍历。

Map集合的方法和Set集合的方法基本一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//声明map
let m = new Map();
m.set('name','guigu');
m.set('age',21);
m.set('change',function (){console.log('hello')})

let keyz = {
'school':'atguigu'
}
m.set(keyz,['BJ','SH','GZ'])
console.log(m)
console.log(m.size)
m.delete('change')
console.log(m)
console.log(m.get(keyz))

4.class类

ES6引入了类的概念,作为对象的模板;通过class关键字,就可以定义类。

ES6的class可以看作只是一个语法糖,新的class写法只是让对象原型的写法更加清晰,更像面向对象编程。

关于类的相关知识点:

  1. 利用class关键字声明类
  2. constructor定义构造函数的初始化
  3. extends表示继承父类
  4. super调用父级构造方法
  5. static定义静态方法和属性
  6. 子类可以重写父类的方法
  7. get和set方法
4.1 基本用法
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
//在ES5中的方法
// function Phone(brand, price) {
// this.brand = brand;
// this.price = price;
// }
// Phone.prototype.call = function (){
// console.log('I can call')
// }
// let Huawei = new Phone('P40',4999)
// Huawei.call();
// console.log(Huawei)


// ES6 class类的写法
class Phone{
//构造方法,名字是固定的constructor
constructor(brand,price) {
this.brand = brand;
this.price = price;
}
//方法必须使用该语法,不能使用ES5的语法
call(){
console.log('I can call!')
}
}
let Xiaomi = new Phone('Xiaomi11',3999);
console.log(Xiaomi)
Xiaomi.call();
4.2 类的静态成员
1
2
3
4
5
6
7
8
//静态属性是属于类的,而不属于实例对象
class Phone{
//定义静态属性
static name = 'horizon'
static age = 21
}
let Hua = new Phone();
console.log(Hua.name) //undefined
4.3 类的继承
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
34
35
36
37
38
39
//ES6继承
class Phone{
constructor(brand,price) {
this.brand = brand;
this.price = price;
}
call(){
console.log(this.brand+'I can call.')
}
}

//子类SmartPhone继承父类Phone
class SmartPhone extends Phone{
constructor(brand,price,color,size) {
super(brand,price); //相当于Phone.call(this,brand,price)
this.color = color;
this.size = size;
}
// 子类特有的方法
photo(){
console.log(this.brand+'I can take photo')
}
playGame(){
console.log(this.brand+'I can play game')
}
//重写父类的方法
call(){
console.log('重写的call方法')
}
}
let p = new Phone('apple',5999)
let xm = new SmartPhone('xm',3999,'black','6.1inch')
p.call()
xm.call()
xm.photo()
xm.playGame()
console.log('-----------------')
console.log(p)
console.log(xm)
4.4 get和set

get方法一般用来获取数据,set方法一般用来设置

1
2
3
4
5
6
7
8
9
10
11
12
13
class Phone {
get price(){
console.log('get方法被调用')
return 'get method'
}
set price(newVal){
console.log('set方法调用')
}
}
let p = new Phone()
console.log(p.price) // 输出 get方法被调用 get method
p.price = 'Hello'
console.log(p.price) //输出 set方法调用,因为给实例p设置了price值,调用了set方法

5.对象方法的扩展

  1. Object.is:判断两个值是否相等
  2. Object.assign:对象的合并
  3. Object.setPrototypeOf设置原型对象
  4. Object.getPrototypeOf获取原型对象
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
//1.Object.is 判断两个值是否完全相等
console.log(Object.is(120,120))

//2.Object.assign 对象的合并
const config1 = {
a:'a',
b:'b',
c:'c',
t:'t1'
}
const config2 = {
d:'d',
e:'e',
f:'f',
t:'t2'
}
console.log(Object.assign(config1,config2)) //如果有重复,后面的会覆盖前面的


//3.Object.setPrototypeOf 设置原型对象
// Object.getPrototypeOf 获取原型对象
const school = {
name:'xinhui'
}
const cities = {
xiaoqu:['SH','GZ']
}
Object.setPrototypeOf(school,cities)
console.log(school)
console.log(Object.getPrototypeOf(school))

6.ES6的模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

6.1 模块化的好处
  1. 防止命名冲突
  2. 代码复用
  3. 高维护性
6.2 模块化的语法

模块化功能主要由两个命令构成:exportimport

export:用于规定模块的对外接口,即暴露

import:用于输入,导入其他模块提供的功能

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!--<script type="module"> //要声明type的类型-->  

<!-- //通用导入方式-->
<!-- //引入 26.模块化.js 模块内容-->
<!-- // import * as m1 from './js/26-模块化.js'-->
<!-- // console.log(m1)-->
<!-- //-->
<!-- //-->
<!-- // //引入 26.模块化2.js 模块内容-->
<!-- // import * as m2 from './js/26-模块化2.js'-->
<!-- // console.log(m2)-->
<!-- //-->
<!-- // //引入 26.模块化2.js 模块内容-->
<!-- // import * as m3 from './js/26-模块化3.js'-->
<!-- // console.log(m3)-->


<!--// 2.解构赋值方式-->
<!-- import {school,teach} from "./js/26-模块化.js";-->
<!-- // console.log(school,teach())-->

<!-- // import {school as s1,teach as t2} from './js/26-模块化2.js';-->
<!-- // console.log(s1,t2)-->
<!-- //-->
<!-- // import {default as m3} from './js/26-模块化3.js'-->
<!-- // console.log(m3)-->
<!-- //-->
<!-- // // 3.简便形式,只能针对默认暴露-->
<!-- // import m4 from "./js/26-模块化3.js"-->
<!-- // console.log(m4)-->
<!--</script>-->

<!--
另一种引入方法,先把模块引入到一个js文件,再使用script标签引入
-->
<script src="js/app.js" type="module"></script>


//部分例子,通用导入方式
import * as m1 from './26-模块化.js'
import * as m2 from './26-模块化2.js'
import * as m3 from './26-模块化3.js'

console.log(m1)
console.log(m2)
console.log(m3)

接口暴露的方式一般有三种:

  1. 分别暴露方式
1
2
3
4
5
6
7
//分别暴露方式
export let school = 'guigu1'
export function teach(){
console.log('we can teach you develop.')
}
//暴露这个模块 只需在前面加上export

  1. 统一暴露方式
1
2
3
4
5
6
7
8
//统一暴露方式
let school = 'guigu2'
function teach(){
console.log('we can teach you develop.')
}

export {school,teach}

  1. 默认暴露方式(常用)
1
2
3
4
5
6
7
//默认暴露方式
export default {
school:'guigu3',
teach:function (){
console.log('we can teach you.')
}
}