闭包
概述:闭包就是函数内部返回一个函数,内部函数有外部函数的引用.这个结构称为闭包
函数的两个阶段
- 函数定义阶段
1. 在内存中开辟了一个函数的存储空间
2. 将函数的代码一模一样的放到该空间中(函数中的变量没有解析)
3. 将函数的存储空间地址 给到函数名(变量)
- 函数调用阶段
1. 根据函数名(变量)中地址,找到函数的存储空间
2. 实参传递给形参
3. 函数中的代码预解析
4. 执行函数中的代码
- 重新解释函数调用阶段
1. 根据函数名(变量)中地址,找到函数的存储空间
2. 在内存中 开辟一个函数的 `执行空间`,在`函数的执行空间`中
3. 实参给形参赋值
4. 预解析
5. 执行函数中代码
6. 函数代码执行结束,函数的 `执行空间` 销毁
- 一个不销毁的函数执行空间
1. 在函数内部需要返回一个复杂数据类型
2. 在函数外部有变量对函数的返回值一直引用着
闭包
概述:闭包就是函数内部返回一个函数,内部函数有外部函数的引用.这个结构称为闭包
- 作用域的嵌套形成的一种函数的高级应用场景
闭包形成条件
1. 大函数的执行空间不销毁
2. 大函数中返回的不是一个对象,而是一个函数
3. 小函数中应用着大函数中的 变量数据
我们就说 小函数就是大函数的 闭包函数
##闭包的特点
- 内部函数可以拥有外部函数的参数和变量的引用,使我们的参数和变量的作用范围被扩大
+ 但是必须得通过闭包的形式访问
- 延长了函数内变量的生命周期
+ 可以让函数中的数据进行缓存(数据持久化)
- 函数的执行空间不销毁,容易造成内存溢出
闭包的用途
###防抖:在规定时间内只执行最后一次
个人认为应该是如果多次触发的时间间隔没有达到定时器的时间间隔就不会触发
###节流(在规定时间内会触发一次,减少执行的次数),一般来说就是指在这个时间内不管你触发多少次,都只会执行第一次
###函数柯里化
将多个参数的函数拆分为多个单参数的函数 可以自由的组合
一句核心就是参数如果和原来的参数数量不同就返回函数,参数够了就返回结果
Promise - 承诺
- 如果你要执行异步代码,给我来执行,我承诺给你一个结果
- 用于 封装执行异步代码的
-
承诺的几个状态
- pending 执行中
- fullfilled/ resolved 成功(resolve调用)
- rejected 失败 -
promise状态变化
- 从 执行中 到 成功
- 从 执行中 到 失败 -
Promise是js中的一个构造函数
使用语法: new Promise(function(第一个参数,第二个参数){})- 两个参数都是回调函数
- 第一个参数(resolve) 执行的时候,状态会变为 成功
- 第二个参数(resolve) 执行的时候,状态会变为 失败
-
promise状态从执行中变为成功会执行的函数
- 语法: promise对象.then(函数)- 注意: 因为resolve回调函数执行了才 触发的状态变为成功,让then中的函数执行,而且resolve调用传入的实参 会传递给then中的函数形参
-
promise状态从执行中变为失败也会执行的函数
- 语法: promise对象.catch(函数)- 注意: 因为reject回调函数执行了才 触发的状态变为失败,让catch中的函数执行,而且reject调用传入的实参 会传递给catch中的函数形参
- 注意2: 我们一般会将catch方法在then方法调用后连贯调用
-
在new Promise中执行代码的时候如果有异常抛出,则默认会将promise状态变为失败的
- 会执行catch中的函数,而且抛出的异常信息会传递给catch方法中的形参(而不会报错) -
promise对象方法的的链式调用(then 和catch都会发生值穿透)
- promsie对象.then().then().then()…catch()- 一般我们只需要写一个catch就可以捕获所有的异常
- 如果then()函数没有返回新的promise对象,则所有then方法中的函数都执行,但是只有第一个then方法中的函数能接到实参
- 如果then()函数中返回了一个新的promise对象,则后续的then()方法执行都依赖这个新的promise对象
- 链式调用中 catch()方法只需要在最后书写,中间任何一个环节有异常抛出,则直接执行catch方法中的函数
-
promise对象的then方法中其实有两个回调函数
- then(函数1,函数2)- 状态为成功的时候,执行函数1,失败的时候执行函数2
-
new promise(函数) 函数中的代码执行是同步的
- promise对象的then和catch方法中的函数代码执行是异步的
promise的静态方法
Promise.方法名
- resolve 方法 返回一个成功的Promise对象
- reject 方法 返回一个失败的Promise对象
- all 并行执行方法 传入一个promise数组 并行执行promise数组里面的promise,返回的是一个promise对象 如果都是成功对应的promiseResult里面的结果就是所有成功 否则就是错误的结果(一个错就都是错)
- allSettled 传入一个promise数组并行执行但是不会互相影响结果 会返回所有的结果 返回的是一个promise对象
- race 传入promise数组 返回最快的promise
1. async关键字 - 用于修饰函数的(包括箭头函数),函数执行完毕会返回一个promise对象 - 作用: 为了在该函数内,可以使用await关键字 2. await关键字 - 只能在 async修饰的函数内使用 - 一般await用于修饰 执行promise - await 的特点 1. await 修饰的语句 之后的代码都是同步执行(要等await修饰的代码执行成功,函数内后续的代码才执行) 2. await 修饰的语法执行的结果(异步的返回值) 会作为 await 这个语句的结果,可以使用变量接收,后续使用 3. 如果async修饰的函数内什么都没有name对应的promise状态是成功(默认函数会返回undefined) 4. await只能在async里面使用 await会使当前的函数陷入等待 ``` //解决回调地狱 function fn(v, delay) { return new Promise((resolve, reject) => { //这一行是同步代码 setTimeout(() => { console.log(v); resolve() }, delay) }) } async function fn1() { await fn(1, 1000) await fn(2, 2000) await fn(3, 300) } fn1()
##代码执行机制
###同步代码执行比异步代码快
同步代码的执行是利用对应的js引擎解析的
异步代码执行是利用事件轮询机制执行的
###事件轮询机制
- 先找到script里面的微任务
- 按照微任务队列执行对应的微任务
- 进入下一个宏任务 执行对应的宏任务代码
- 进行宏任务对应微任务队列执行对应微任务
- 再进行到下一个宏任务 执行对应的微任务
- 直到对应的宏任务队列和微任务队列被清空
####宏任务
script标签 定时器 事件
####微任务
promise.then promise .catch nextTIck