闭包
概述:
函数嵌套函数,内部函数拥有外部函数的引用,对应的外部的函数的这个引用不会被gc回收。
作用域
全局作用域 (global)
里面的this指向对应的global对象 也就是说对应的全局作用域的变量其实都是global对象的属性
局部作用域 (函数作用域)
函数的预编译过程
局部作用域
1. 创建AO对象 (Activation Object 执行上下文)(开辟的内存空间)(会在堆中开辟一个跟函数名一样名字的空间)
2. 给函数里面的形参、变量进行赋值操作 (undefined)
3. 形参和实参同步
4. 找到函数声明 赋值给函数体
function fn(a=1,b=2){
console.log(a,b,c) //1,2,undefined
var c = function(){
console.log(1)
}
console.log(c) //函数
}
fn()
console.log(a) //function
var a = 10
function a(){}
console.log(a) //10 (全局污染)
全局作用域(全局暴露 对变量来说有全局污染的问题)
1. 创建GO对象 (Global Object 全局对象)(给对应的global对象添加属性)
2. 给函数里面的形参、变量进行赋值操作 (undefined)
3. 形参和实参同步
4. 找到函数声明 赋值给函数体
console.log(a) //function
var a = 10
function a(){}
console.log(a) //10 (全局污染)
函数执行过程
去堆中找到对应的函数名所有对应的地址,放入执行栈中执行(压栈)
执行过程中(开辟对应的执行空间)使用的对应执行上下文进行执行(函数体)
返回对应的结果(结果不会销毁)
执行完(销毁对应的执行空间 以及对应的函数体) (出栈)
实现一个函数调用一次自增一次
从上述代码可以得到对应函数中return 一个引用数据类型 在这个引用数据类型内容保持对应的外部的一个参数或者是变量的引用那么这个变量将不会被回收。(扩大了函数内容变量的作用范围)
闭包的优缺点
优点
防止变量的全局污染 (这个变量是局部变量)
扩大了变量的作用域
缓存对应的数据
缺点
过度使用闭包容易造成内存泄漏 (当前这个空间已经没用了 但是空间没有被销毁)
对应内存的耗费大(性能差) (内部函数时刻保持对应的外部函数变量或者参数的引用)
闭包的用途
作为缓存 (容量小 速度快)
防抖
节流
函数柯里化
防抖(debounce)
概述:
在规定时间内只执行一次 (执行最后一次)
案例:
坐电梯
代码实现
function debounce(callback,waitTime){ //第一个是执行的函数,第二个是等待事件
var timer
return function(){ // 闭包
//清除上一次定时器
clearTimeout(timer)
timer=setTimeout(function(){
//调用执行的函数
callback()
//清除定时器
clearTimeout(timer)
},waitTime)
}
}
let fn=debounce(function(){
console.log(123)
},1000}//调用封装的函数
//设置点击事件
document.querySelector("button").onclick=fn
节流 (throttling)
在规定时间内执行第一次,执行完继续执行。(减少对应的次数)
案例
高铁厕所案例
代码实现
function throttling(callback,waittime){
var timer //设置节流阀
return function(){
//判断节流阀是否使用
//未使用就开始操作
if(!timer){
timer = setTimeout(function(){
callback()//调用执行操作
clearTimeout(timer)
timer =null //设置为未使用状态
},waittime)
}
}
}
let fn=debounce(function(){
console.log(123)
},1000}//调用封装的函数
//设置点击事件
document.querySelector("button").onclick=fn
函数柯里化
将一个多参数的函数 分成多个函数(彼此之间可以任意组成)
示例
简单函数柯里化
高阶函数柯里化
函数柯里化核心
参数个数没到对应的个数返回的是函数 参数个数到了返回的是值
Promise
概述:
ES6新增的一个类,用于解决异步问题的(替代回调函数)
promise的三种状态
等待 pedding
成功 fulfiiled(有对应的处理)
失败 rejected (有对应的处理)
promise的构建
异步代码如何同步执行
使用回调函数
通过以上代码会发现回调函数嵌套过深会导致回调地狱问题 (回调地狱它的代码没有可用性 要避免)
使用promise来解决对应的回调地狱
核心在对应的then方法返回一个新的promise 再调用下一个then
promise的方法及属性
属性 (内置属性 无法访问)
PromiseState 表示当前状态
PromiseResult 表示当前的结果
方法
原型方法
then (处理对应的一个promise状态变化的)
then有俩个参数函数 一个是成功的处理函数
一个是拒绝的错误函数
成功的处理函数里面可以接收对应的resolve函数调用携带的参数
拒绝的处理函数里面可以接收对应的reject函数调用携带的参数
拒绝的处理函数还可以捕获的对应的promise中抛出的错误
在then中return的数据会被下一级的then方法接收
then里面会发生值穿透 (上层的then方法没有对应的函数做为参数)
catch 捕获promise错误 以及获取对应的promise的reject方法调用的结果 (跟then方法中的第二个
参数一模一样)
finally 状态发生变化就会调用的函数
静态方法
resolve 产生一个状态为成功的promise
reject 产生一个状态为拒绝的promise
reac 竞速 (传入一个promise数组 返回执行完成最快的promise)
all 并行执行传入promise数组 (遇到了rejected那么就获取到rejected的promise 如果全部成功会接收所有的promise结果)
allsettled 并行执行传入promise数组 (只要执行完成那么返回都是对应的成功状态 且会接收所有的promise结果)
async及awiat
概述
async和awiat是es7新增的修饰关键词,async是用于修饰对应的函数的,被async修饰的函数 执行会返回一个promise对象,awiat和async属于语法糖 (awiat一定要在async里面使用 且awiat修饰的是promise)
async
概述
async表示异步、async是用于修饰函数的 且修饰的函数调用会返回一个promise对象
注意事项
修饰的函数内容返回值相当于调用了resolve方法 返回的值会被传递给then
在修饰函数内报错相当于调用了reject方法 错误会被传递给catch
awiat
概述
awiat是用于修饰promise的,它只能在async修饰的函数内使用,它会让当前的(js引擎线程在当前的执行上下文中等待)等待,当前修饰promise的状态不为pending的时候就会释放。
使用async和awiat解决回调地狱
EventLoop
概述:
eventLoop事件轮询,针对于对应的异步任务的执行相关操作(定时器、事件、请求....)。
事件队列
队列是先进先出一个数据结构,事件队列就是其异步任务的一个队列(先进去先执行 后进行后执行)
执行栈
栈是一个先进后出的一个数据结构,它主要用执行对应的js代码。
事件队列的分类
宏任务 (大的任务 线程直接分配的)
script 标签
定时器(setInterval,setTimeout)...
微任务 (小的任务)
promise.then promise.catch promise.finally
宏任务进入宏任务队列 微任务进入微任务队列
eventLoop主要是控制宏任务队列的任务执行及微任务队列的任务执行
先宏后微
一个个的宏任务走进再走其包含的微任务