ES6的认识

文章详细介绍了ECMAScript6(简称ES6)的一些关键特性,包括箭头函数的简洁语法和this指向规则,以及Promise对象在处理异步操作中的应用。此外,还提到了模块化在JavaScript中的重要性以及导入导出的机制。箭头函数简化了函数表达,而Promise解决了回调地狱问题,提高了异步编程的可读性和维护性。
摘要由CSDN通过智能技术生成

ECMAScript是欧洲计算机协会提出的规范,我们JS的语法就是用这个语法,Javascript分为三部分ECMAScript + DOM + BOM

IE8浏览器支持ES3,IE9之后支持ES5,没有ES4,因为ES4的修改过于激进,所以没有成为标准。2015年ES2015标准提出。从这个标准之后,ES版本都是以年份作为描述,前端界还会以数字称呼,称为ES6。每一年ECMAScript都会新增一些新的api,但是新增的内容都比较少,所以我们统称后续的ECMAScript为ES6+。

新出的标准浏览器兼容性不好,有一个插件应运而生Babel,可以帮助我们把ES6代码转换成ES5代码,基本上,这个转换过程是无感的。所以我们在开发时,可以肆无忌惮使用ES6语法,也推荐大家使用ES6语法。

箭头函数

箭头函数是函数的一个新的写法,它能够带来更简便的函数写法。

let fn = () => {}

把原本的function删除,然后在()后面添加了=>,所有的箭头函数都是匿名函数。

箭头函数可以简化的写法

我们使用箭头函数函数时会遇到一下简化写法

  • 只有一个参数
  • 只有返回值
  • 只有返回值且返回值是一个对象

只有一个参数

只有一个参数时,不需要添加 ()可以省略

正常函数

let fn = function (参数) {}

转成箭头函数

let fn = (参数) => {}

简化后

let fn = 参数 => {}

只有返回值

正常函数

let fn = function () {
  return "返回值"
}

箭头函数

let fn = () => {
  return "返回值"
}

简化后

let fn = () => "返回值"

返回值如果是对象

普通函数

let fn = function () {
  return {key: "value"}  
}

箭头函数

let fn = () => {
  return {key: "value"}  
}

简化

let fn = () => ({key: "value"})

注意!!!!!推荐大家使用箭头函数,但是对象中的方法不要用箭头函数,事件函数不要用箭头函数,因为箭头函数的this指向和普通函数不一样。

箭头函数的this指向问题

箭头函数中的this指向谁!!!声明箭头函数时,箭头函数所在作用域的this指向。

JavaScript中this指向的问题 - 掘金

箭头函数的这个特性解决了什么问题呢???

btn.onclick = function () {
  this.innerText = "加载中……"
  // let _this = this
  axios.get("https://cnodejs.org/api/v1/topics").then((res) => {
    console.log(this)
    // 使用了箭头函数,我们就不需要再事先获取到this,然后再使用新的变量
    this.innerText = "加载完成"
    // _this.innerText = "加载完成"
  })
}

分析之前的代码

fetch(url).then(res => res.json())
let arr = [1,2,3,4]

arr.map(function (num) {
  return num + 1
})

arr.map(num => num + 1)
let fn = () => () => () => () => 1

Promise

承诺,在声明函数时承诺好,如果成功就执行resolve,如果失败就执行reject。定义resolve和reject函数的人,是使用这个Promise对象的人。

Promise有三个状态,分别时等待中,成功,失败。

注意!!!!三个状态只能成等待中变成成功,或者从等待中变成失败,如果已经成功成功或者失败,就不能再改变状态

function 异步函数 () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 模拟几率
      if (Math.random() > 0.5) {
        // 来了
        resolve()
      } else {
        reject()
      }
    }, 3000)
  })
}
异步函数().then(() => {
  // resolve函数
  console.log("一起走")
}).catch(() => {
  console.log('自己走')
})

为什么有些函数调用之后,可以调用.then方法

axios.get().then(res => {}).catch(() => {})

因为这些函数在封装时,上来返回了一个new Proimise。promise对象中有三个方法。

  • then(() => {}) 异步操作成功时执行的函数
  • catch(() => {}) 异步操作失败时执行的函数
  • finally(() => {}) 不管成功还是失败都会执行的函数。

我们今天的目标是,未来看到.then或者.catch时,知道这个函数内部返回了一个promise对象。后一个.then里的参数,是前一个.then return的结果

函数().then(() => {
  return 1
})
.then(num => {
  // num就是1
  
})

Promise中所有的方法.then.catch.finally调用之后,都会返回这个promise对象。并且会按链式的顺序执行对应的then中的方法

数组方法

forEach map filter find findIndex some every reduce reduceRight

filter

筛选,调用后得到一个数组,这个数组的内部结构和原数组相同,长度大概率不同,会变少。

arr.filter((item) => {
  return true 或者 false 
  // 如果上面返回true 则item就会被放在新数组中,如果为false,则不执行任何操作。
  // 所谓的新数组,是我们对应的filter的返回值
})

some

判断某个数组中是否有符合条件的值。返回值为布尔值

arr.some(item => true或者false) 

只要有一个返回值为true,则停止遍历,返回some的结果为true,如果都返回false,则some结果为false

every

判断某个数组中是否全部符合条件的值。返回值为布尔值

与some相反,只要有一个不符合条件,结果为false,如果全部都符合条件,则结果为true

arr.every(item => true 或者 false)

find

用来查找第一个符合条件的值

返回值是第一个符合条件的值,只要第一次函数中返回true,则会把正在遍历的item给作为返回值返回

arr.find(item => true 或者 false)

findIndex

用来查找第一个符合条件的值的下标

arr.find(item => true 或者 false)

reduce/reduceRight

每次遍历都会保留上一次的返回值

arr.reduce((prevValue, curValue, index, arr) => {

  return 值 // 这个值是下一次函数执行的prevValue
}, 初始值) // 初始值是第一次函数执行的prevValue

flat

扁平化数组,没有flat函数我们需要自己封装递归函数进行扁平化。

arr.flat(层数)

如果我们不知道有几层的情况下,可以使用Infinity

arr.flat(Infinity)

fill

在数组对应的位置范围填充相同的值

arr.fill(值, 开始下标, 结束下标) // 后两个值可选

Array.of()

可以把参数变成数组

Array.of(1, 2, 3) // [1,2,3]

静态方法

直接设置给构造函数上的方法,叫静态方法,不需要new直接使用构造函数调用即可。数组中有三个静态方法

  • Array.from
  • Array.isArray
  • Array.of

解构赋值

解构赋值,可以实现直接从数组或者对象中取值赋值给变量

let [变量名, 变量名2, , 变量名4] = [值, 值2, 值3, 值4]
// 相当于
let 变量名 = 数组[0]
let 变量名2 = 数组[1]
let 变量名4 = 数组[3]


let { 变量名, 变量名2 } = { 属性名: "值", 变量名2(本质是属性名): "值" } // 属性名和变量需要相同

let { a, b } = { a: 1, b: 2 } 

解构赋值很容易遇到一种情况,我们要使用的名字和已有变量名冲突(重复)了

let name = "张三"

let {name, age} = {
  name: "李四",
  age: 18
}

// 因为name已经声明了,所以第三行的name就会报错:变量已经声明
// 我们可以使用别名解决这个问题
let {name: 别名, age} = {
	name: "李四",
  age: 18
}

// 别名就是变量名

参数解构

我们可以把函数的形参进行解构,在函数内部可以直接使用解构后的值,更方便使用

function fn (obj) {
	console.log(obj.x, obj.y)
}

fn({x: 1, y: 2})


function fn2 ({x, y}) {
  console.log(x, y)
}
fn({x: 1, y: 2})


function fn3 ([x, y]) {
}

fn3([1,2])

扩展运算符

扩展运算的作用可以简单理解为:把数组的中括号,和对象的{}直接去掉。直接去除后,里面的数据格式,我是无法在JS的环境的中独立存在。扩展运算符的操作需要被放置在合适的位置上。

let arr = [1,2,3]
let _arr = [...arr] // [1,2,3] 这是一个浅拷贝过程

let obj = {a: 1, b: 2, c: 3}
let _obj = {...obj} // {a: 1, b: 2, c: 3} 这是一个浅拷贝过程

let arr2 = [...arr, ...arr] // [1,2,3,1,2,3]

在我们使用map操作时,可以保留原有数据的基础上,添加新的属性

let arr = [{name: "张三"}, {name: "李四"}]

arr.map(stu => {
  return {
    ...stu,
    classroom: "王屋山"
  }
})

rest参数

这个运算符可以用来代替arguments。当遇到不定参数时,可以使用rest。

function sum (...nums) {
  nums就是一个数组,传参时我们需要传很多个单个的值,这些值会被放在一个数组中,这个数组就是nums
}

sum(1,2,3) // nums就是[1,2,3]

可以把剩余没有声明形参的参数收集变成数组

function fn (a, b, c, ...args) {}

fn(1, 2, 3, 4, 5, 6) // a 1 b 2 c 3 args是[4,5,6]

对象中的新写法

属性写法

当属性的名字和变量相同时,我们可以只写一个属性名即可

let name = "张三"

let obj = {
  // name: name
  name
}

方法写法

当我们要设置方法时,可以直接省略 :function

let obj = {
  // fn: function () {},
	fn () {
    
  }
}

async await

异步函数,可以把函数内部的异步操作转换为同步写法。

async function 函数名 () {
  let res = await 原始值或者Promise对象
  // 下面的代码,会等上面的异步处理结束后才执行。
}


async getData () {
  let res = await axios.get("接口地址", {params: {参数}})
  // 处理res
}

因为变成了同步操作,同时代码有可能得到错误信息,如果要处理错误,可以是try catch

async getData () {
  try {
    let res = await axios.get("接口地址", {params: {参数}})
  	// 处理res
  } catch (err) {
  	// 处理错误操作
  }
}

重要!!!!async函数,返回值是一个promise对象。所以我们如果要得到函数里的自己的返回值,需要使用.then获取

async function fn () {

  return 10
}

fn().then(res => {
	// res 就是 10
})

// 或者如果还要用async 就需要再封装一个函数(比较麻烦)
async function init () {
	let num = await fn()
  console.log(num) // 10
}

init()

函数

函数参数默认值

ES6中提出了函数参数默认值的写法

function fn (形参="默认值") {
  console.log(形参)
}

fn() // 默认值

如果不传参,则默认就是对应的默认值

下面的知识不属于ES6

arguments

表示函数调用时实际传入的参数的集合,是一个类数组对象。一般函数不定数量参数时可以使用arguments

arguments.callee

这个就表示函数本身,在一些匿名函数完成递归调用时使用。

模块

这个知识点很重要。

模块化发展历史单独引入js->CommonJS(nodejs)->AMD(require.js)->CMD(sea.js)->UMD->ESModule(现在主流的)

前置条件

想要在浏览器中使用模块化,需要在script标签添加type="module",并且需要在服务器环境下打开。

<script type="module"></script>

导出模块

导出模块有两种方法

  • export
  • export default

export default

默认导出(最方便的导出方式),这种导出方式只能导出一次,如果想要多次导出,就需要使用export进行导出。这种方式不需要我们考虑命名的问题。

export default 任意值

所谓的任意值,可以是任意的数据类型。

export

可以导出多个模块

// 第一种方法
export let 变量名 = 任意值

// 第二种方法
let 变量名 = 任意值

export {
  // 如果变量名和模块名一致
  变量名,
	变量名 as 模块名 // 一般导出时不改名字
  
}

导入模块

导入模块使用import 有三种导入方式

import 导入默认导出的模块

这种操作最简单,不需要考虑名字,自己自定义一个即可。

import 自定义的名字 from "模块文件路径"

注意!!!如果模块中没有 export default,则会报错。

import 导入 export导出的模块

使用export导出的模块,在导入时,名字需要和导出时的名字一致

import { 模块名 } from "模块文件路径"
// 如果有多个模块需要导入,则使用 "," 隔开
import { 模块名, 模块名2, 模块名n } from "模块文件路径"
// 如果要导入的模块名和现有变量有冲突,我们可以改名字
import { 模块名 as 别名, 模块名n } from "模块文件路径"
// 如果我们不知道里面有什么模块,想要全部导出作为对象查看
import * as 自定义的名字 from "模块文件路径"

当一个模块中既有默认导出,又有普通导出,导入可以一起写

import 自定义名字 from "模块路径"
import {模块名} from "模块路径"

// 可以写在一起
import 自定义名字, {模块名} from "模块路径"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值