ES6~13 基础入门

1. 什么是 ES6?

  • ES6 是 ECMAScript 6 的简称,是 JavaScript 的最新版本。
  • 学习 ES6 可以更好的编写 JavaScript 代码,提高代码的可读性、可维护性和可扩展性。
  • 学习 ES6 可以更好的使用 JavaScript 进行开发,比如使用模板字符串、箭头函数、类、模块化、Promise、异步迭代器等。

2. 变量和常量

变量和常量,之前学习java已经明白含义,这里不再赘述。

2.1 变量声明

使用let关键字声明变量,变量的值可以被修改。

// 声明变量name 并进行赋值 十一月
let name = "十一月"
// 打印输入
console.log(name)
// ${} 占位符实现字符串拼接
console.log(`Hello ${name}`)
// 输出 name的数据类型
console.log(typeof name)

let money = 100

console.log(money)
console.log(`money ${money}`)
console.log(typeof money)

let balance = 99.99

console.log(balance)
console.log(`balance ${balance}`)
console.log(typeof balance)

let flag = true

console.log(flag)
console.log(`flag ${flag}`)
console.log(typeof flag)

输出

十一月
Hello 十一月
string
100
money 100
number
99.99
balance 99.99
number
true
flag true
boolean

es6不区分整数型和浮点型,统一用number表示。

注意console.log()就是一个输出语句,可以用来输出变量的值,打印到控制台输出。

2.2 常量声明

使用const关键字声明常量,常量的值不能被修改。

//声明常量 money 赋值为100
const money = 100
// 占位符输出
console.log(`I have ${money} dollars.`)
//尝试修改常量的值
money = 200
console.log(`I have ${money} dollars.`)

输出

I have 100 dollars.
money = 200
      ^

TypeError: Assignment to constant variable.

可以看到,我们尝试修改常量值时,运行就会直接报错。

3. 数据类型

同java一样,es6中也有很多数据类型,接下来会进行一一演示。但是这里只是简单解释,具体用法后面会再次介绍。

3.1 字符串类型-string

字符串类型,使用单引号或双引号括起来的字符序列。

// 声明字符串类型变量
let name = "syy hello!"
// 输出变量值
console.log(name)  //syy hello!
// 字符串拼接,占位符输出
console.log(`${name} World`)  //syy hello! World

注意:这里使用字符串拼接输出${name},需要使用反引号**``**进行包裹,一定要搞清楚!

3.2 数值类型-number

数值类型,包括整数和浮点数。

let money = 100
let banlace = 99.99
console.log(money, banlace) // 100 99.99
console.log(money + banlace) // 199.99

注意:数值类型可以进行加减乘除运算。

3.3 布尔类型-boolean

布尔类型,只有两个值,true和false。

let flag = true
console.log(flag) // true

注意:布尔类型只有true和false,不能进行其他运算。

3.4 对象-object

类似json数据格式,键值对模式

// 定义一个对象 data,包含name、age、city属性
let data = {
    name: "John",
    age: 30,    
    city: "New York"
}
console.log(data)   // { name: 'John', age: 30, city: 'New York' }

3.5 键值对集合-map

类似java中的map,是一个键值对的集合,但是在这里,是有序的集合。

// 定义一个map集合,包含name、age、city属性
let map = new Map([
    ["name","John"],
    ["age", 30],
    [999,888]
])
// 如果不想初始化就赋值,可以先定义一个空的map集合,然后使用set方法添加键值对
// let map = new Map()
// map.set('name', 'John')
// map.set('age', 30)


console.log(map.get("name")) //  John
console.log(map.get("age")) //  30
console.log(map.get(999)) //  888

注意:map集合的键值对是有序的,可以通过get方法获取值。而且需要通过new Map()的方式定义,并且使用的是[]的方式定义键值对,键值对中间使用的是,分隔。

3.6 无序集合-set

类似java中的set,是一个无序的集合,只能存放唯一的元素。

// 声明并赋值
let set = new Set([1,2,3,5])

// 先声明  后通过add方法添加元素
// let set = new Set()
// set.add(1)
// set.add(2)
// set.add(3)
// console.log(set)  //  Set(3) { 1, 2, 3 }

3.7 数组-array

数组是一中有序集合,注意这里,可以存放不同类型的数据,长度可变。

// 定义包含不同类型的数组
let array = [1,2,3,4,5,"6"]
//输出
console.log(array)   // [1, 2, 3, 4, 5, "6"]

// array.add(7) // 报错,add方法不存在

array.push(8) // 正确,push方法可以添加元素到数组末尾

console.log(array)   // [1, 2, 3, 4, 5, "6", 8]

3.8 函数-function

函数是js的核心,可以用来实现各种功能。

// 定义add函数,实现计算 x+y 并返回,不需要指定参数类型 即不需要像在java方法中 int x,int y
function add(x,y){
    return x+y
}

// 调用add函数
console.log(add(1,2)) // 3

3.9 类-class

类是js的面向对象编程的基础,可以用来实现各种功能。

class Person{
    // 构造函数,实例化对象时调用,这里设置了两个属性
    constructor(name,age){
        this.name = name
        this.age = age
    }

    // 实例方法
    info(){
        console.log(`name: ${this.name}, age: ${this.age}`)
    }
}

// 实例化Person对象并调用info方法  其实就相当于 const person = new Person("大海","66") person.info()
new Person("大海","66").info() // name: 大海, age: 66

4. 函数

上面已经简单说了函数的定义,这里再详细说一下。

//定义普通函数
function getWeb(){
    let web = "blog.xy21lin.cn"
    // console.log(web)

    return web
}

//调用方法
console.log(getWeb())   //blog.xy21lin.cn


//定义传参函数
function getWebUrl(url){
    // console.log(url)
    return url
}
// 定义变量url
let url = "blog.xy21lin.cn"
// 调用函数并传参
console.log(getWebUrl(url))   //blog.xy21lin.cn


// 定义默认值函数
function getWebUrlDefault(url = "blog.xy21lin.cn"){
    // console.log(url)
    return url
}

// 调用默认值函数不传参
console.log(getWebUrlDefault())   //blog.xy21lin.cn
// 调用默认值函数并传参
console.log(getWebUrlDefault("4399.com"))   //4399.com


/** 匿名函数
 *  匿名函数,就是没有名字的函数,被视为一个表达式,通常作为回调函数使用,也就是把函数作为参数传递给另一个函数。
 *  回调函数:特定事件或条件发生时被调用的函数,回调函数一般用于异步操作中,就比如success就是Ajax请求中的一个回调函数,处理请求成功的结果。
 */

// 定义匿名函数 并赋值给 sub 变量
let sub = function(x,y){
    return x-y
}
console.log(sub(10,5))  //5


// 箭头函数,其实也是匿名函数,但是省略了function
let add = (a,b) => {
    return a+b
}
/**这里函数体只有一行代码的话, 就可以省略{}和return,也叫隐式返回
 * let add = (a,b) => a+b
 * 这样写也就相当于
 * let add = function(a,b){  return a+b}
 */
console.log(add(1,2)) // 3

5. 数组

前面简单了解了数组定义,这里详细介绍数组的使用。

// 定义一个数组并赋值
let arr = [1,2,3,4,5,6]
// 使用push方法添加一个元素或多个元素到数组末尾中,并返回修改后的数组长度
let arrLength = arr.push(99,88,77)
// 输出数组长度
console.log(arrLength) // 9
// 输出数组
console.log(arr)  // [1, 2, 3, 4, 5, 6, 99, 88, 77]

// 使用unshift方法添加一个元素或多个元素到数组开头中,并返回修改后的数组长度
let arrLength1 = arr.unshift(50,40,30)
// 输出数组长度
console.log(arrLength1) // 9
// 输出数组
console.log(arr)  // [50, 40, 30, 1, 2, 3, 4, 5, 6, 99, 88, 77]

// 使用shift方法删除数组中第一个元素,并返回删除的元素
let arrShift = arr.shift()
// 输出删除的元素
console.log(arrShift) // 50

// 使用pop方法删除数组中最后一个元素,并返回删除的元素
let pop1 = arr.pop()
console.log(pop1) // 77

// 使用splice方法删除数组中指定索引元素,并返回被删除元素的数组
// 索引从0开始,要删除元素的索引,后是删除元素个数
// 删除arr元素,从第五个开始,删除五个,也就是第5,6,7,8,9个元素
// 对应数组中索引也就是 4,5,6,7,8
// 对应数组中元素就是 3,4,5,6,99
let delArr = arr.splice(4,5)
console.log(delArr) //[3,4,5,6,99]

// reverse方法,颠倒数组中的元素
let reverseArr = arr.reverse()
console.log(reverseArr) // [ 88, 2, 1, 30, 40 ]

// sort方法,对数组进行排序,默认是对字符串排序,可能会导致数字排序不正确
let arr1 = ["balance","apple","egg"]
let sortArr = arr1.sort()
console.log(sortArr) // [ 'apple', 'balance', 'egg' ]

// 定义一个数字数组并排序,发现输出结果不是按照数字大小排序的
let arr2 = [5,20,13,4,1]
let sortArr1 = arr2.sort()
console.log(sortArr1) // [ 1, 13, 20, 4, 5 ]
// 为了解决这个问题,所以需要自定义排序函数,通过sort方法传入比较函数实现
/**
 * 比较函数 (a,b) => a - b ,接收两个参数a,b,比较a和b的大小,返回a - b
 * 结果 a < b 说明a比b小,a应该在b前面
 * 结果 a = b 说明a和b相等,位置不变
 * 结果 a > b 说明a比b大,a应该在b后面
 * 从而实现升序排序,也就是从小到大
 * 如果想实现降序排序,改成 b - a 即可
 */
let soryArr2 = arr2.sort((a,b) => a-b)
console.log(soryArr2) // [ 1, 4, 5, 13, 20 ]

// filter方法 过滤或者说筛选 数组元素,返回符合条件的元素组成的新数组
let arr3 = [50,90,44,33,64,57,66,15,3,69,4]
// 过滤出数组arr3中大于40的元素
let filterArr = arr3.filter(item => item >40)
// 打印输出
console.log(filterArr) // [ 50, 90, 64, 57, 66, 69 ]

// concat 将多个数组合并成新数组
let arr4 = ["十一月的早晨","吹进卧室的风"]
let arr5 = ["夕阳西下","雨声中洗澡","月光下午的露珠","晚风吹过的窗台"]
// 合并两个数组,arr5数组元素跟在arr4数组元素后面
let concatArr = arr4.concat(arr5)
console.log(concatArr) 
// [ '十一月的早晨', '吹进卧室的风', '夕阳西下', '雨声中洗澡', '月光下午的露珠', '晚风吹过的窗台' ]

// for循环输出数组
for(let i=0i<arr.lengthi++){
    console.log(arr[i])
}

// for of 循环输出
for(let item of arr){
    console.log(item)
}

// forEach循环输出
arr.forEach(item => {
    console.log(item)
})

6. Set集合和扩展运算符

同样,详细介绍set使用。

//声明并赋值set集合
let set = new Set(['apple','banana','pear','orange'])
//add方法添加新元素到集合末尾
set.add("cherry")
console.log(set) // Set(4) {"apple", "banana", "pear", "orange", "cherry"}
// delete方法删除指定元素
set.delete('pear')
console.log(set) // Set(4) {"apple", "banana", "orange", "cherry"}
// has方法检查set集合是否包含指定元素
console.log(set.has('banana')) // true
// size属性 获取set集合大小
console.log(set.size) // 3
// Array.form()方法将set集合转数组
let arr = Array.from(set)
console.log(arr) // (4) ["apple", "banana", "orange", "cherry"]
// 使用扩展运算符将set集合转数组
let arr1 = [...set]
console.log(arr1) // (4) ["apple", "banana", "orange", "cherry"]
// 扩展运算符将字符串转数组
let str = '十一月的早晨'
let strArr = [...str]
console.log(strArr) // (12) ["十", "一", "月", "的", "早", "晨"]
// for of 遍历set
for(let item of set){
    console.log(item)
}
// forEach遍历set
set.forEach((item) =>{
    console.log(item)
})
// clear方法清空set
set.clear()
console.log(set) // Set(0) {}
// 将数组转set,实现数组去重
let arr2 = [1,2,3,4,5,6,6,5,8,9,4,1]
let set2 = new Set(arr2)
console.log(set2) // Set(6) {1, 2, 3, 4, 5, 8, 9}

6. Map集合

同样,详细介绍map使用。

//创建空map集合
// let map = new Map()

// 声明并赋值map集合
let map = new Map([
    ["name","十一月"],
    ["age",22],
    ["habbit","music"]
])

// set方法    添加元素 注意是键值对格式
map.set("city","太原")
console.log(map)  // Map(4) { 'name' => '十一月', 'age' => 22, 'habbit' => 'music','city' => '太原' }
// delete方法 删除元素
map.delete("habbit")
console.log(map)   // Map(3) { 'name' => '十一月', 'age' => 22, 'city' => '太原' }
// has方法    检查元素是否存在(作为键)
console.log(map.has("habbit")) // false
// size属性   获取map集合大小
console.log(map.size) // 3
// Array.from方法  map集合转数组
let arr = Array.from(map)
console.log(arr)   // [ [ 'name', '十一月' ], [ 'age', 22 ], [ 'city', '太原' ] ]
// 扩展运算符将map集合转数组
let arr1 = [...map]
console.log(arr1)  // [ [ 'name', '十一月' ], [ 'age', 22 ], [ 'city', '太原' ] ]

// for of循环打印
//[key, value] 就是一种解构语法, 用于将 Map 集合中的键值对解构为 key 和 value 两个变量
for(let [key,value] of map){
    console.log(key,value)
}

// forEach方法打印
map.forEach((value,key) =>{
    console.log(key,value)
})
// clear方法 清空map集合
map.clear()
console.log(map)

7. 对象Object

详细介绍对象使用。

// 定义一个对象
let person = {
    name: "John",
    age: 30,
    city: "New York"
}

// 对象中添加属性
person.gender = "male"
// 对象中修改属性
person.age = 28
// delete 删除属性
delete person.city
// in 检查属性是否存在
let has = "city" in person
console.log(has)   // false
// 获取对象属性数量
console.log(Object.keys(person)) // 获取对象名数组,类似获取map键 集合   
// [ 'name', 'age', 'gender' ]
console.log(Object.keys(person).length) // length属性获取数组长度
// 3

// 对象转数组   类似map获取键值对集合 
let arr = Object.entries(person)
console.log(arr)
// [ [ 'name', 'John' ], [ 'age', 28 ], [ 'gender', 'male' ] ]

// for in 遍历对象
for(let key in person){
    console.log(key, person[key])
}

// forEach遍历对象属性和值
Object.entries(person).forEach(([key,value]) =>{
    console.log(key, value)
})
// name John
// age 28
// gender male

// 清空对象
person = {}
console.log(Object.keys(person).length)   // 0

注意:forEach是先使用Object.entries()方法获取键值对集合,然后再遍历集合,所以forEach方法的回调函数接收到的参数是键值对数组([key,value]),而不是键和值(key,value)

8. 类Class

详细说明类的定义、属性、私有属性、存取器、继承。

8.1 存取器

class Person{
    //如果不手动声明设置属性,直接再构造函数中调用属性,则会默认创建对应属性
    name //姓名
    age  //年龄
    #gender //性别 使用#声明,就表示为私有属性
    //构造函数
    constructor(name,age,gender){
        this.name = name
        this.age = age
        this.#gender = gender
    }

    //使用 getter方法和setter方法  或者说 存取器 获取和设置私有属性
    getter(){
        return this.#gender
    }

    setter(gender){
        this.#gender = gender
    }


    //方法
    info(){
        return `My name is ${this.name} and I am ${this.age} years old.My gender is ${this.#gender}`
    }
}

//实例化对象 通过new
let person = new Person("十一月",22,"保密")
//调用实例属性
console.log(person.name,person.age) //输出:十一月 22
//调用实例方法
console.log(person.info()) // 输出:My name is 十一月 and I am 22 years old.My gender is 保密

// 通过setter方法设置私有属性
person.setter("男")
// 通过getter方法获取私有属性
console.log(`私有属性gender:${person.getter()}`) // 输出:私有属性gender:男
//再次调用实例方法
console.log(person.info()) // 输出:My name is 十一月 and I am 22 years old.My gender is 男

8.2 继承extends

// 定义父类
class Person{
    constructor(name,gender){
        this.name = name;
        this.gender = gender;
    }

    sleep(){
        return `${this.name}正在休息中~`
    }
}


// 定义子类 使用extedns关键字继承父类
class JimBaby extends Person{
    constructor(name,gender,age){
        // 调用父类的构造函数 super
        super(name,gender);
        this.age = age;
    }
    
    eat(){
        return `${this.name}正在吃饭~`
    }
}


//实例化子类对象
let jim = new JimBaby('JimBaby','male',18)
//调用父类的sleep()方法
console.log(jim.sleep())
//调用子类的eat()方法
console.log(jim.eat())
// JimBaby正在休息中~
// JimBaby正在吃饭~

9. 解构

解构, 即将数组或对象中的元素提取出来,并赋给变量

9.1 数组解构

// 数组解构
// 将1赋值给x  2赋值给y
let [x,y] = [1,2]
console.log(`${x} and ${y}`) // 1 and 2

// 我想获取数组中的第3个元素,就用两个,再用变量去接收
let [,,c] = [1,2,3,4,5,6]
console.log(c) // 3
// 我想将 1 赋值给a,23456赋值给b
let arr = [1,2,3,4,5,6]
let [a,...b] = arr
console.log(a) // 1
console.log(b) // [2, 3, 4, 5, 6]

// 现在数组只有一个值,但是我想赋值给两个值,会发生什么
let [x1,y1] = [99]
console.log(`${x1} and ${y1}`) // 99 and undefined
// 可以看到,因为数组只有一个值,所以x1获得到了值,但是y2没有所以为underfined,这个时候就可以设置默认值
let [x2,y2=100] = [99]
console.log(`${x2} and ${y2}`) // 99 and 100

// 两数交换 通过x3和y3位置对调,实现两数交换
let [x3,y3] = [100,200];
[x3,y3] = [y3,x3]
console.log(`${x3} and ${y3}`) // 200 and 100

9.2 对象解构

// 对象结构
let person = {
    name: 'John',
    age: 30,
    city: 'New York',
}

let {name} = person; // 解构赋值,只提取出name属性
console.log(name); // John

// 重命名 将name属性重命名为alias,主要是为了解决命名冲突,而不是修改对象中的属性名
let {name: alias,age} = person; 
console.log(alias,age); // John 30

// 默认值  没有gender属性,可以去指定一个默认值进行使用
let {city,gender='male'} = person; 
console.log(`${city} and ${gender}`); // New York and male

10. 字符串

详细介绍字符串常用方法使用。

// 声明并赋值字符串
let web = "blog.xy21lin.cn"

// length属性 获取字符串长度
console.log(web.length) // 13
// toLowerCase() 方法 转换成小写字母
console.log(web.toLowerCase()) // blog.xy21lin.cn
// toUpperCase() 方法 转换成大写字母
console.log(web.toUpperCase()) // BLOG.XY21LIN.CN
// 返回索引位置字符 也就是数组下标索引
console.log(`${web[0]},${web[1]},${web[2]},${web[3]}` )

// [...] 扩展运算符 字符串转数组
let arr = [...web]
console.log(arr) // ["b", "l", "o", "g", ".", "x", "y", "2", "1", "l", "i", "n", ".", "c", "n"]

// parseInt() 方法 字符串转int
let num = "123"
console.log(typeof parseInt(num)) // number

// replace() 方法 字符串替换
let str1 = "hello world"
// 将world 替换为 syy
console.log(str1.replace("world","syy"))    // hello syy

// trim() 方法 去除字符串两侧指定字符
let str2 = "  hello world  "
// 去除两端空格
console.log(str2.trim()) // hello world
let str3 = "!hello world!"
// 去除两端的!
console.log(str2.trim("!")) // hello world

// includes() 方法 是否包含某个字符串
console.log(web.includes("xy21lin"))    // true

// indexOf() 方法 返回字符在字符串中第一次出现的位置,不存在返回 -1 从0开始
console.log(web.indexOf("21"))   //7
console.log(web.indexOf("syy"))  // -1

// startsWith() 方法 是否以指定前缀开头
console.log(web.startsWith("blog")) // true

// endsWith() 方法 是否以指定后缀结尾
console.log(web.endsWith(".cn")) // true

// split() 方法 将字符串按照指定字符分割成数组
let str4 = "a,b,c,d,e"
//按照,分割成数组
console.log(str4.split(","))

// substring(开始位置,结束位置) 和substr (开始位置,截取长度) 方法 截取字符串 从0开始
// substring 含头不含尾
console.log(web.substring(0,4)) // blog
// 从索引为4开始,省略了结束位置,默认到末尾
console.log(web.substring(4))   // xy21lin.cn
// 参数为负数,则会认为0
console.log(web.substring(-3))  // blog.xy21lin.cn

// 从索引为4开始,截取长度为3
console.log(web.substr(4,3)) // .xy
// 省略第二个参数,则截取到末尾
console.log(web.substr(4))   // .xy21lin.cn
// 设置为负数,则从后开始截取
console.log(web.substr(-3))  // .cn

// repeat(重复次数) 方法 重复字符串
console.log("hello".repeat(3)) // hellohellohello

// padStart() 方法 在字符串前添加指定数量填充字符,直到达到指定长度
// 设置长度为18,从左开始填充字符-  直到字符串长度为18
let padStr = web.padStart(18,"-")
console.log(padStr) // ---blog.xy21lin.cn

// padEnd() 方法 在字符串后添加指定数量填充字符,直到达到指定长度
// 设置长度为18,从左开始填充字符-  直到字符串长度为18
let padEndStr = web.padEnd(18,"-")
console.log(padEndStr) // blog.xy21lin.cn---

11. Promise

Promise 表示承诺在未来的某个时刻可能会完成并返回结果。使用在异步编程之中。

对于某些需要时间来处理结果的操作, 如用户登录、读取文件等, 可以使用 Promise 对象来执行异步操作

Promise 对象有三种状态 pending(待处理)fulfilled(已履行)rejected(被驳回)

  1. 当创建一个 Promise 对象时, 它的初始状态为 pending, 表示异步执行还未完成

  2. 当异步执行成功时, 会调用 resolve 函数把 Promise 对象的状态改变为 fulfilled, 可通过 then 方法来获取异步操作的结果

  3. 当异步执行异常时, 会调用 reject 函数把 Promise 对象的状态更改为 rejected, 可通过 catch 方法来处理错误

        /*
            let promise = new Promise((resolve, reject) => {
                
            })

            //当创建一个 Promise 对象时, 它的初始状态为 pending, 表示异步执行还未完成
            console.log("promise:", promise) //pending
        */

        /*
            let promise = new Promise((resolve, reject) => {
                resolve("邮件发送成功") //异步执行成功
            })
            //当异步执行成功时, 会调用 resolve 函数把 Promise 对象的状态改变为 fulfilled, 可通过 then 方法来获取异步操作的结果
            console.log("promise:", promise) //fulfilled

            promise.then(result => {
                console.log("result:", result)
            })
        */

        /*
            let promise = new Promise((resolve, reject) => {
                reject("邮件发送失败") //异步执行失败
            })
            //当异步执行失败时, 会调用 reject 函数把 Promise 对象的状态更改为 rejected, 可通过 catch 方法来处理错误
            console.log("promise:", promise) //rejected

            promise.catch(error => {
                console.log("error:", error)
            })
        */

            let promise = new Promise((resolve, reject) => {
                //resolve("邮件发送成功")
                reject("邮件发送失败")
            }).then(result => {
                console.log("result:", result)
            }).catch(error => {
                console.log("error:", error)
            }).finally(() => {
                console.log("异步执行结束")
            })

注意:异步操作是指在程序执行过程中, 某个操作不会立即返回结果, 而是需要一段时间的等待, 直到操作完成后才会返回结果。

12. Fetch

fetch 是基于 Promise 的 api, 它可以发送http请求并接收服务器返回的响应数据,fetch 返回的是一个 Promise 对象。

基本语法: fetch(url, options)

  • url: 请求的url地址
  • options: 请求的配置选项,可以设置请求方法、请求头、请求体等。

12.1 fetch实现get请求

    //get请求
    fetch('http://127.0.0.1/get').then(response => {
        //返回的解析后的json数据会传递给下一个 then() 方法中的回调函数作为参数,这个参数就是 data
        return response.json() //response.json() 用于将响应数据解析为json格式的数据
    }).then(data => { //data 解析后的json数据
        console.log("get.data:", data)
    }).catch(error => {
        console.log("get.error:", error.message)
    }).finally(() => {
        console.log("get.finally")
    })

12.2 fetch实现post请求,提交表单数据

    //post请求 post
    fetch('http://127.0.0.1/post', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },            
        body: new URLSearchParams({//URLSearchParams 用于处理键值对类型的数据,并将其编码为url查询字符串
            name: '十一月',
            address: '太原',
        }),
    }).then(response => {
        return response.json()
    }).then(data => {
        console.log("post.data:", data)
    }).catch(error => {
        console.log("post.error:", error.message)
    }).finally(() => {
        console.log("post.finally")
    })

12.3 fetch实现post请求,提交JSON数据

    //post请求 postJson
    fetch('http://127.0.0.1/postJson', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({//JSON.stringify 用于将对象转换为json字符串
            name: '十一月',
            address: '太原',
        }),
    }).then(response => {
        return response.json()
    }).then(data => {
        console.log("postJson.data:", data)
    }).catch(error => {
        console.log("postJson.error:", error.message)
    }).finally(() => {
        console.log("postJson.finally")
    })

13. Axios

Axios 是基于 Promise 的网络请求库, 它可以发送http请求并接收服务器返回的响应数据, Axios 返回的是一个 Promise 对象。不仅可以适用于浏览器, 也可以用于 Node.js, 而 Fetch 主要用于浏览器。

基本语法: axios(config)

  • config: 请求的配置选项,可以设置请求方法、请求头、请求体等。
    // 使用前确保安装了axios  
    // npm install axios
    // 确保安装后,在项目中引入axios模块
    const axios = require('axios');


    //get请求
    axios.get('http://127.0.0.1/get').then(response => {
        console.log("get.data:", response.data)
    }).catch(error => {
        console.log("get.error:", error)
    }).finally(() => {
        console.log("get.finally")
    })

    //post请求 post
    let data = { //参数
        name: '十一月',
        address: '太原',
    }

    //表单模式请求
    axios.post('http://127.0.0.1/post', data, {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    }).then(response => {
        console.log("post.data:", response.data)
    }).catch(error => {
        console.log("post.error:", error)
    }).finally(() => {
        console.log("post.finally")
    })

    //post请求 postJson [axios 的默认请求头是 application/json]
    axios.post('http://127.0.0.1/postJson', data).then(response => {
        console.log("postJson.data:", response.data)
    }).catch(error => {
        console.log("postJson.error:", error)
    }).finally(() => {
        console.log("postJson.finally")
    })

14. 模块化开发

模块化开发是指将复杂的代码拆分为独立的模块,每个模块负责完成特定的功能。

不同的模块之间可以通过使用export关键字将代码导出为模块,其他模块可以使用import关键字导入该模块

14.1 分别导出分别导入

let name = "十一月"
let webUrl = "blog.xy21lin.cn"
let copyRight = "枫月堂"
let info = () => "This is a demo"

export {name, webUrl, copyRight,info}
    <script type="module">
        import {name, webUrl, copyRight,info} from './demo1.js'

        console.log(name) // 十一月
        console.log(webUrl) // blog.xy21lin.cn
        console.log(copyRight) // 枫月堂
        console.log(info()) // This is a demo
    </script>

14.2 默认导出对象导入

let name = "十一月"
let webUrl = "blog.xy21lin.cn"
let copyRight = "枫月堂"
let info = () => "This is a demo"

export default {name, webUrl, copyRight,info}
    <script type="module">
        import obj from './demo1.js'

        console.log(obj.name) // 十一月
        console.log(obj.webUrl) // blog.xy21lin.cn
        console.log(obj.copyRight) // 枫月堂
        console.log(obj.info()) // This is a demo
    </script>

14.3 分别导出对象导入

let name = "十一月"
let webUrl = "blog.xy21lin.cn"
let copyRight = "枫月堂"
let info = () => "This is a demo"

export {name, webUrl, copyRight,info}
    <script type="module">
        import * as obj from './demo1.js'

        console.log(obj.name) // 十一月
        console.log(obj.webUrl) // blog.xy21lin.cn
        console.log(obj.copyRight) // 枫月堂
        console.log(obj.info()) // This is a demo
    </script>

15. 同步方式编写异步代码

同步代码是指在执行过程中, 代码的执行顺序与代码的编写顺序一致, 即按照代码的顺序从上到下执行。

异步代码是指在执行过程中, 代码的执行顺序与代码的编写顺序不一致, 即代码的执行顺序与代码的执行顺序不一致。

异步代码的执行顺序, 取决于事件循环, 事件循环是指程序运行过程中, 用于处理并执行异步代码的机制。

async 和 await 关键字是 ES2017 引入的新语法, 用于编写异步代码。
async 关键字用于定义一个异步函数, 该函数返回一个 Promise 对象。
await 关键字用于等待一个 Promise 对象, 直到该 Promise 对象状态变为 fulfilled, 才会继续执行后续代码。只能在 async 函数内部使用, 加上 await 关键字后, 会在执行到这一行时暂停函数的剩余部分,等待网络请求完成,然后继续执行并获取到请求返回的数据, 也就相当于同步请求。

使用 await 关键字来等待 Axios 的 Promise 结果。使得异步代码看起来更像同步代码,从而更易于理解和维护,从而避免了回调地狱(callback hell)和复杂的 Promise 链。

15.1 回调地狱

回调地狱(Callback Hell)是指在使用异步编程时,由于回调函数嵌套过多导致代码难以阅读和维护的情况。通常发生在需要执行多个异步操作,并且每个操作都需要依赖前一个操作的结果时。这种情况下,代码往往会形成一个“金字塔”形状,使得逻辑变得复杂且难以追踪。

//get请求
    axios.get('http://127.0.0.1/get').then(response => {
      console.log("get.data:", response.data)
      if (response.data.data.web == "xxxxxxx") {
        //get请求2
        return axios.get('http://127.0.0.1/get2').then(response2 => {
          console.log("get2.data:", response2.data)
          if (response2.data.data.name == "xxxxxxx") {
            //get请求3
            return axios.get('http://127.0.0.1/get3').then(response3 => {
              console.log("get3.data:", response3.data)
            })
          }
        })
      }
    }).catch(error => {
      console.log("get.error:", error)
    }).finally(() => {
      console.log("get.finally")
    })

15.2 使用 async 和 await

const axios = require('axios');

// 定义一个异步函数
const fetchData = async () => {
    try {
        // get请求
        const getResponse = await axios.get('http://127.0.0.1/get');
        console.log("get.data:", getResponse.data);

        // post请求 post
        const postData = {
            name: '十一月',
            address: '太原',
        };
        const postResponse = await axios.post('http://127.0.0.1/post', postData, {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });
        console.log("post.data:", postResponse.data);

        // post请求 postJson [axios 的默认请求头是 application/json]
        const postJsonResponse = await axios.post('http://127.0.0.1/postJson', postData);
        console.log("postJson.data:", postJsonResponse.data);
    } catch (error) {
        console.log("error:", error);
    } finally {
        console.log("finally");
    }
}

// 调用异步函数
fetchData();