JS高阶
2022-12-22 16:14:00 17 举报
AI智能生成
高阶函数是指能够接受其他函数作为参数或返回值的函数。在JavaScript中,高阶函数可以对函数进行抽象和封装,使得代码更加灵活、可复用性更高。常见的高阶函数包括:map、filter、reduce、sort等。此外,高阶函数还可以实现柯里化、偏函数等功能,为编写复杂的逻辑提供便利。总之,掌握高阶函数是成为一名优秀的前端开发者所必备的技能之一。
作者其他创作
大纲/内容
闭包
闭包:指的是 有权访问另外一个函数作用域变量的 函数
为什么会产生闭包?
因为当程序到了一定程度复杂之后,我们就会出现函数嵌套函数的情况出现
闭包的形成是在函数定义的时候形成的,而不是函数执行的时候(在判断this指向的时候)
闭包的表现形式:
1. 函数作为参数被传递
2. 函数作为返回值被返回
直接看函数定义的地方
1. 函数作为参数被传递
2. 函数作为返回值被返回
直接看函数定义的地方
闭包的优缺点(作用意义)
1. 优点:将全局的变量私有化,防止外部篡改
实现变量的持久化保存,防止局部变量被销毁(垃圾回收机制==》浏览器机制)
2. 缺点:占用内存,造成内存泄漏
1. 优点:将全局的变量私有化,防止外部篡改
实现变量的持久化保存,防止局部变量被销毁(垃圾回收机制==》浏览器机制)
2. 缺点:占用内存,造成内存泄漏
防抖
都是优化高频事件的一种优化手段
防抖的作用:用户点击n次,但是效果只执行一次
防抖的作用:用户点击n次,但是效果只执行一次
防抖作用:用户触发n次事件后,只有一次触发(第一次或最后一次)
防抖用在 点击 input事件
防抖用在 点击 input事件
实现方式:每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法
总结:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,
但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
节流
节流作用:在同一段时间内,时间的触发频率减少
使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行
使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行
实现方式:每次触发事件时,如果当前有等待执行的延时函数,则直接return
触发事件的时间戳 curtime(触发时时间点) 大于startime(开始时时间点)
判断两个事件的时间间隔是否满足我设置的时间间隔
判断两个事件的时间间隔是否满足我设置的时间间隔
时间戳小于0
说明事件处理函数可以触发
时间戳大于0
说明事件在我们限制的间隔时间内,不能让他继续触发
开启一个定时器,延迟事件的执行
开启一个定时器,延迟事件的执行
节流常用:sroll--浏览器下拉 resize
节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖只是在第一次或者最后一次事件后才触发一次函数。
比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。
这样的场景,就适合用节流技术来实现。(总结)
比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。
这样的场景,就适合用节流技术来实现。(总结)
事件循环
事件循环是js的一个机制:宏任务和微任务
js是一门单线程语言:指的是js一个时间内只能做一件事
同步任务:简单理解,普通代码 可以一行一行的立刻执行编译
异步任务:简单理解,能被js编辑器编译,但是不会立刻执行,等待某个条件触发后才会执行代码
也可以看作中断的代码,先忽略,然后再回头触发
同步任务:简单理解,普通代码 可以一行一行的立刻执行编译
异步任务:简单理解,能被js编辑器编译,但是不会立刻执行,等待某个条件触发后才会执行代码
也可以看作中断的代码,先忽略,然后再回头触发
异步任务的经典例子:
定时器 事件处理函数 ajax 其余的代码都是同步任务
区分同步和异步任务的关键点:看代码中是否有回调函数
定时器 事件处理函数 ajax 其余的代码都是同步任务
区分同步和异步任务的关键点:看代码中是否有回调函数
规则:宏任务一定比微任务晚执行
宏任务的执行是比微任务要后执行
只有异步任务才分下面两个:
宏任务:定时器 事件处理函数 ajax
微任务:promise async...await
如何区分:es6的就是微任务 ECMA
es6之前的产物都是宏任务 W3C
产生任务区分的原因:他们定义的机构不一样
宏任务的执行是比微任务要后执行
只有异步任务才分下面两个:
宏任务:定时器 事件处理函数 ajax
微任务:promise async...await
如何区分:es6的就是微任务 ECMA
es6之前的产物都是宏任务 W3C
产生任务区分的原因:他们定义的机构不一样
事件循环有什么用?
程序的执行机制(程序的结构),执行顺序,是用于等待和发送消息和事件
模块化
什么是模块化
将一个页面的js拆分成了若干份---方便阅读,提高维护性和效率
如:entry.js 拆分成 utils.js工具类 index.js逻辑js 主要处理页面逻辑
如:entry.js 拆分成 utils.js工具类 index.js逻辑js 主要处理页面逻辑
有什么用?
ES Module(前端常用)
是来自ES6定下来,它是从js语言本身层面,实现了模块化
使用了3个关键字 export import default
使用了3个关键字 export import default
step1 新建a.js 定义任意数据类型 通过export关键字暴露
step2 使用模块化的script标签 需要设置type="module"
step3 通过关键字import 引入 需要的数据
step4 直接使用即可 注意:网页打开方式是 Open the Live server
step2 使用模块化的script标签 需要设置type="module"
step3 通过关键字import 引入 需要的数据
step4 直接使用即可 注意:网页打开方式是 Open the Live server
第1~第4 阶段
AMD CMD (这是两个退出了历史舞台的两个模块化规范)
前端模块化的火种,
AMD -- require.js
CMD -- sea.js
两分天下,都有属于直接的代表着(js库:js一个集合) swiper.js 提供一个捷径来快熟
实现某些功能,如swiper.js
AMD CMD (这是两个退出了历史舞台的两个模块化规范)
前端模块化的火种,
AMD -- require.js
CMD -- sea.js
两分天下,都有属于直接的代表着(js库:js一个集合) swiper.js 提供一个捷径来快熟
实现某些功能,如swiper.js
- this指向
什么是this指向?
拥有不同的对象,在于它所属的位置
在方法中,this指的是所有者对象,也就是谁调用
单独使用的情况下,this指向的是全局对象 window
在函数中,函数的拥有对象默认绑定this
在事件中,this指的是接受事件的元素
指的是所属的对象
作用:可以使开发过程中,很多相识或相同的代码提供一个优雅、简便的对象引用。从而让代码更加简洁
箭头函数
语法:()=>代码
语法:()=>代码
如何判断this指向
this指向:函数定义所在的作用域 也叫上下文
作用:简化函数的编写和this指向
普通函数function()
this指向:谁调用指向谁
改变this指向
call(你要改变的对象,具体的实参...)
apply(你要改变的对象,[具体的实参...])
bind(你要改变的对象,具体的实参...) 返回一个函数,需要调用它 后面加();
如何判断 this 指向问题
1.判断当前this所在函数是不是箭头函数
箭头函数看作用域
普通function函数看谁调用
2.注意看有没有改变this指向
正则表达式
作用:本质就是字符串的操作
正则它的服务对象一定是字符串
总结字符串+正则表达式的完成的功能:
1. 查找
2. 替换
3.验证 用户信息(验证注册登录)
4.分割
总结字符串+正则表达式的完成的功能:
1. 查找
2. 替换
3.验证 用户信息(验证注册登录)
4.分割
字符串方法
split 拼接
let str = "abc123df123"
let reg = /123/g;
console.log(str.split(reg));// ['abc', 'df', '']
let str = "abc123df123"
let reg = /123/g;
console.log(str.split(reg));// ['abc', 'df', '']
search 查找
let reg = /e/g;
console.log(str.search(reg));
//能找到返回具体下标,找不到返回-1
let reg = /e/g;
console.log(str.search(reg));
//能找到返回具体下标,找不到返回-1
replace 替换
let reg = /\d/g//数字正则
console.log(str.replace(reg,"*"));//abc***df***
let reg = /\d/g//数字正则
console.log(str.replace(reg,"*"));//abc***df***
正则常用方法
test()常用
功能:判断字符串中是否满足正则条件
参数:你要判断的字符
返回:布尔值 满足时true 反之是false
功能:判断字符串中是否满足正则条件
参数:你要判断的字符
返回:布尔值 满足时true 反之是false
例子:let str ="dffdsfd12324vfgf";
let reg = /123/g //123数字
console.log(reg.test(str));//true
let reg = /123/g //123数字
console.log(reg.test(str));//true
exec() 通常搭配()一起使用
功能:判断字符串中是否满足正则条件
参数:你要判断的字符
返回:满足正则条件的字符数组
功能:判断字符串中是否满足正则条件
参数:你要判断的字符
返回:满足正则条件的字符数组
let str ="dffdsfd12324vfgf123";
let reg = /(123)/g //123数字
console.log(reg.exec(str));//['123', '123']
let reg = /(123)/g //123数字
console.log(reg.exec(str));//['123', '123']
正则转义字符
- \w 匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
- \W 除了\w以外的
- \W 除了\w以外的
\d 0-9 数字
\D 非\d
\D 非\d
\s 空格 匹配所有 是匹配所有空白符,包括换行
\S 非空格 \S 非空白符,不包括换行
\S 非空格 \S 非空白符,不包括换行
--^ --$ --\b --\B ^--以开头匹配 $--以结尾 \b--是否存在边界 \B 非\b
数量相关
{}的三次写法 {具体次数} {最低,最高} {最低,正无穷}
? 相当于{0,1} 特别注意
+ 相当于 {1,}
如何创建正则表达式
语法结构:/具体匹配的内容/标识符 --i --g(常用) --m
字面量创建 let reg = /abc/g
str.match() 结合正则一起用的字符API
字面量创建 let reg = /abc/g
str.match() 结合正则一起用的字符API
标识符 i g m
g 全局 全部查找一遍
i ignore 忽略大小写
m 换行
g 全局 全部查找一遍
i ignore 忽略大小写
m 换行
通过构造函数创建
let reg = new RegExp("具体匹配的内容","标识符");
let reg = new RegExp("具体匹配的内容","标识符");
AJAX
ajax是什么? 类似是前端和后台数据 的 桥梁,向后台请求数据信息
有什么作用?
作用是:它是一种无需重新加载整个网页的情况下,实现网页的部分信息更新
AJAX实现方法:
let xhr = new XMLHttpRequest();//(1.联系)
let url = "http://jsonplaceholder.typicode.com/posts?_limit:5&_page:1" //2.填写地址
后面的参数 当page=2 的时候 就会请求后面的数据
后面的参数 当page=2 的时候 就会请求后面的数据
let method = "GET"; //3.选择请求方式 "GET" "POST"
"GET"
参数是放在url上,造成安全极差
请求常用于获取数据
请求常用于获取数据
"POST"
参数放在请求体放在send()中,相对安全···
请求常用于修改或提交数据
请求常用于修改或提交数据
xhr.open(method,url); // 给钱
xhr.send(); //发货 发送请求
xhr.send(); //发货 发送请求
xhr.onreadystatechange = function(){ //等待收货
满足条件1.xhr.readyState === 4
(readyState 0 1 2 3 4 状态机 是会随着ajax不同的阶段)
(readyState 0 1 2 3 4 状态机 是会随着ajax不同的阶段)
2.xhr.status === 200
//status http的状态码
//status http的状态码
3.接受数据:xhr.responseText--但是此时是一种JSON格式
JSON格式 非常严格 一定是双引号
JSON.stringify(obj);//正常对象转JSon格式 {"a":1,"b":2}
JSON.parse(obj)//json转正常对象 {a: 1, b: 2}
4.const data = JSON.parse(xhr.responseText);--转换成正常对象
参数
简单理解:细分请求
比如更改的请求没有参数的时候,直接返回100条
但添加了参数_limit=5 之后,数据值返回了5条
比如更改的请求没有参数的时候,直接返回100条
但添加了参数_limit=5 之后,数据值返回了5条
如果发送请求不成功?
一般检查三个原因
1.看地址是否正确 2.看请求方式 3.看请求参数
ES6方法
设计目标:方便前端人员的代码的编写,简化编写
设计目标:方便前端人员的代码的编写,简化编写
定义变量:
let、const
let、const
let const 都不是将变量挂载到window上
挂载到了window中的一个叫golbal的属性上
挂载到了window中的一个叫golbal的属性上
const 定义常量,不被修改的内容
let 是随意更改
优先推荐使用const,这样可以保证数据的安全性不被随意修改
- 只有当我们明确知道一个变量后续会被重新赋值的时候,才会去使用let
let 是随意更改
优先推荐使用const,这样可以保证数据的安全性不被随意修改
- 只有当我们明确知道一个变量后续会被重新赋值的时候,才会去使用let
数组解构 位置 一一对应
let a = 1;
let b = 2;
[a,b] = [b,a]//[2,1]
console.log(a,b);//2 1
对象解构
let a = 1;
let b = 2;
[a,b] = [b,a]//[2,1]
console.log(a,b);//2 1
对象解构
let str ="dadadadaf" 查找字符方法
console.log(str.includes("z"));//查找 z 是否存在 返回布尔值
console.log(str.startsWith("z"));//查找 z 是否存在于开头 返回布尔值
console.log(str.endsWith("z"));//查找 z 是否存在于开头 返回布尔值
console.log(str.includes("z"));//查找 z 是否存在 返回布尔值
console.log(str.startsWith("z"));//查找 z 是否存在于开头 返回布尔值
console.log(str.endsWith("z"));//查找 z 是否存在于开头 返回布尔值
数组方法
Array form :伪数组转换真数组
findIndex 找下标
每个元素都会走一次判断,成立返回当前元素的下标
找不到就是-1
每个元素都会走一次判断,成立返回当前元素的下标
找不到就是-1
fill(填充的数据,起始位置,结束位置) 填充 可以完成一些替换的工作
第一个参数填充的数据,第二个参数和第三个参数 填充的起始位置和结束位置
第一个参数填充的数据,第二个参数和第三个参数 填充的起始位置和结束位置
flat 扁平化数组 展开数组
扩展运算符 和 剩余参数 ...
let arr = [1,2,3]
let arr = ["a","b","c"]
[...arr7,...arr8] 123 abc
把原本的内容打开,将元素裸露出来 =》扩展运算符
集合 打散 合成个体
let arr = [1,2,3]
let arr = ["a","b","c"]
[...arr7,...arr8] 123 abc
把原本的内容打开,将元素裸露出来 =》扩展运算符
集合 打散 合成个体
Set Map
es5 是没有的
Set作用就是用来去重
arrSet 这个对象有个特点
成员独立 唯一性 能自动完成去重工作
es5 是没有的
Set作用就是用来去重
arrSet 这个对象有个特点
成员独立 唯一性 能自动完成去重工作
let arr11 = [1,23,32,2,3,2,3,5,1]
let arrSet = new Set(arr11);//1,23,32,2,3,5
let arrSet = new Set(arr11);//1,23,32,2,3,5
对象新增方法
Object.assign(被合并,将要被合并,将要被合并)
对象的合并
对象的合并
Map 新对象
let objNormal ={
a:1,
b:2
}
objNormal["a"] = 10;
console.log(objNormal.a);
let objNormal ={
a:1,
b:2
}
objNormal["a"] = 10;
console.log(objNormal.a);
[object HTMLBodyElement] 浏览器自动转成字符串
因为对象key值 只能接收字符串 es5 中比较限制的地方
Map就是为了解决这个
因为对象key值 只能接收字符串 es5 中比较限制的地方
Map就是为了解决这个
Promise
Promise是:内置在js的实例化对象方法
我们new一个Promise对象之后
[[PromiseState]]"pending" 状态
[[PromiseResult]]undefined 结果
[[PromiseState]]"pending" 状态
[[PromiseResult]]undefined 结果
.then是Promise对象的一个方法
规则1 调用resolve() 自动触发.then方法的回调函数
[[PromiseState]]"fullfilled" 状态
[[PromiseResult]]resolve 方法传递过来的参数 结果
规则1 调用resolve() 自动触发.then方法的回调函数
[[PromiseState]]"fullfilled" 状态
[[PromiseResult]]resolve 方法传递过来的参数 结果
规则2 调用reject() 自动触发.then方法的回调函数2
[[PromiseState]]"reject" 状态
规则3 [[PromiseResult]]rejecte 方法传递过来的参数 结果
在一个promise中,成功回调和失败回调只能触发一个,
靠resolve 或reject,这两个调用谁先调用就会改变对应的状态,并且这个状态是不可扭转
[[PromiseState]]"reject" 状态
规则3 [[PromiseResult]]rejecte 方法传递过来的参数 结果
在一个promise中,成功回调和失败回调只能触发一个,
靠resolve 或reject,这两个调用谁先调用就会改变对应的状态,并且这个状态是不可扭转
规则4 ,then方法的链式调用
成功回调返回的内容 并且也是会被包装成一份promise对象
成功回调返回的内容 并且也是会被包装成一份promise对象
promise的方法
1. promise.resolve()
Promise.resolve(1).then(res=>{console.log(res);})
Promise.reject(2).then(res=>{console.log(res);},err=>{console.log(err);})
Promise.resolve(1).then(res=>{console.log(res);})
Promise.reject(2).then(res=>{console.log(res);},err=>{console.log(err);})
Promise.all(数组:这个中所有的元素都是Promise对象)
等待数组中所有的Promise对象都触发了resolve方法后,才会触发.then()
等待数组中所有的Promise对象都触发了resolve方法后,才会触发.then()
Promise.race()
在数据中等待 之前一个promise对象触发resolve,只要其中一个触发了 就会触发.then
Promise.race([p1,p2,p3]).then(res=>{console.log("触发了race方法的.then");})
在数据中等待 之前一个promise对象触发resolve,只要其中一个触发了 就会触发.then
Promise.race([p1,p2,p3]).then(res=>{console.log("触发了race方法的.then");})
p.then() resolve触发的
p.catch() reject触发的
p.finally() 不管reject,还是resolve都会自动执行
p.catch() reject触发的
p.finally() 不管reject,还是resolve都会自动执行
注意:.then(成功回调,失败回调)的失败回调 和.catch() 都是可以被reject()触发的
如果两个方法(失败回调(优先级))和 .catch()同时存在,肯定会走自己的失败回调(记住)
reject()失败的时候调用的,程序发生错误的时候或者因某个程序失败 而触发
如果两个方法(失败回调(优先级))和 .catch()同时存在,肯定会走自己的失败回调(记住)
reject()失败的时候调用的,程序发生错误的时候或者因某个程序失败 而触发
如:一个p对象中有两个.then 都没有失败回调,自动走catch 坏处:统一把错误信息放在catch 不知道是哪个错误
但是两个.then 都有失败回调,走对应的失败回调 好处:能精确定位到哪个.then有问题,分情况使用方法
但是两个.then 都有失败回调,走对应的失败回调 好处:能精确定位到哪个.then有问题,分情况使用方法
有什么用?
是用来破回调地狱--嵌套回调函数
0 条评论
下一页