前端知识点总结
事件捕获,事件冒泡,事件代理
- 事件捕获
- 事件捕获指的是事件响应(点击事件等...)从外层的Window开始,逐级向内层前进,直到具体事件目标元素
- 事件冒泡
- 事件冒泡是从最底层开始一层一层往外传递,直到传递到最外层的Window
- 停止事件冒泡,事件处理函数里使用 e.stopPropagation()即可.直接return false,表示:即停止事件冒泡,也阻止默认事件(e.preventDefault())
- 事件代理
- 事件代理就是利用事件冒泡或者事件捕获的机制把一系列的内层元素事件绑定到外层元素
- 使用事件代理的好处
- 减少内存消耗和dom操作.每一个事件处理函数,都是一个对象,多一个事件处理函数,内存就会被多占用一部分空间.
- 动态绑定事件.因为事件绑定在父级元素,所以新增的子元素也能触发同样的事件.
- 三者的顺序
- DOM事件流的三个阶段是先捕获阶段,然后是目标阶段,最后才是冒泡阶段.
- 在目标事件中的顺序是根据事件捕获,事件冒泡注册的顺序来执行的.
- 给dom元素添加事件处理:addEventListener(event,function,useCapture)
- 第三个参数默认为false,也就是默认为事件冒泡.
- 为true,默认为事件捕获.
总结:
- DOM事件流有3个阶段捕获阶段,目标阶段,冒泡阶段;三个阶段的顺序:捕获阶段--目标阶段--冒泡阶段
- 对于非目标阶段的元素,事件响应执行顺序遵循先捕获后冒泡的原则;
- 对于目标元素,事件响应执行顺序为事件的执行顺序.
- 事件捕获是从顶层Window逐层向内执行,事件冒泡则相反.
- 事件委托是根据事件冒泡或者事件捕获的机制来实现.
async await
async函数
- async是generator加promise的语法糖
- 返回值是一个promise对象
-
- return的值是prmise resolved的value
-
- thorw的值是promise rejected的reason
async function fn(){
return 1;
}
const f = fn()
consoloe.log(p) // 打印结果为一个promise对象 状态是resolved,value是1
/* 打印结果
Promise{<fulfilled>:true}
[[Prototype]]:Promise
[PromiseState]:"fulfilled"
[[PromiseResult]]:1
*/
await函数
- 只能出现在async函数内部或者最外层
- await的promise的状态为rejected,后续执行中断
- await后可以跟pormise和非promise,如果为非promise,例如:await 1,就返回1 await 等待的promise状态是rejected的情况
async function f(){
await Promise.reject("error");
//后续代码不会执行
await 100;
}
f();
// 解决方案 1
async function f(){
await Promise.reject("error").catch(err=>console.log(err))
await 100;
}
// 解决方案2 使用try catch包裹
async function f(){
try{
await Promise.reject("error").catch(err=>console.log(err))
}catch(err){
console.log(err);
}
await 100;
async 简易版实现
async函数是Generator和Prmoise的语法糖 使用generator实现 因为async的返回值是promise对象,在generator中返回promise对象即可 参考文章:juejin.cn/post/710836…
// 核心实现代码
function generatorToAsync(generatorFn){
return function (){
const gen = generatorFn.apply(this,arguments);
return Promise((resolve,reject)=>{
function go(key,arg){
let res;
try{
// gen.next() 可以写成gen[next]();
res = gen[key](arg);
}catch(err){
return reject(err);
}
const [value,done] = res;
if(done){
resolve(value)
}else{
return Promise.resolve(value).then(
val=>go("next",val),
err=>go("throw",err)
);
}
}
go("next");
}
)
}
}
// 用例
function * gen(){
const num1 = yield fn(1);
const num2 = yield fn(num1);
const num3 = yield fn(num2);
return num3;
}
function fn(num){
return new Promise(resolve => {
setTimeout(() => {
resolve(nums * 2)
}, 1000)
})
}
const asyncFn = generatorToAsync(gen);
asyncFn().then(res=>console.log(res)); // 8