今天就给大家讲几个面试高频的知识点
1. commonJS和ES6模块的区别
首先,我理解的他们俩的作用都是导出模块的变量和方法,他们的本质是js模块系统的规范
commonJS模块输出的是一个值的拷贝,它是同步加载模块的机制,也就是加载完模块然后才执行
注意点:需要注意的是,不能直接将
exports变量指向一个值,因为这样等于切断了exports和module.exports之间的联系而且当我们重复
require一个模块时候 commonJS不会多次执行改文件,而是去拿第一次执行该模块的缓存 直接读取第一次使用的缓存
ES6模块输出的是一个值的引用
两者的区别
- CommonJS模块是运行时加载,ES6模块是编译时输出接口
- CommonJS模块输出的是一个值的复制,ES6模块输出的是值的引用
- CommonJS加载的是整个模块,即将所有的方法全部加载进来,ES6可以单独加载其中的某个方法
- CommonJS中
this指向当前模块,ES6中this指向undefined - CommonJS默认非严格模式,ES6的模块自动采用严格模式
2. 微任务和宏任务
先来铺垫几个知识点:
地球人都知道JavaScript是单线程执行的
JavaScript的运行是靠Event Loop事件循环
在浏览器环境中,有JS 引擎线程和渲染线程,且两个线程互斥。Node环境中,只有JS 线程。
执行栈是一个存储函数调用的栈结构,遵循先进后出的原则
最重要的来啦 就是微任务和宏任务的运行机制
- 很多人都以为微任务的执行顺序优先于宏任务,所有就是微任务先执行宏任务后执行 但是执行栈第一个执行的并不是微任务,而是
新程序的执行(它就是一个宏任务) - 然后才运行js代码,先回执行同步任务,例如
console.log() - 然后会把微任务和宏任务进行分类,分类完成后清空调用栈
- 然后事件循环就会先执行微任务,微任务执行完成后就会开始下一轮宏任务 这样就可以避免因为宏任务的繁重导致任务的堵塞
- 当微任务队列被清空后 并不是立即执行宏任务,而是取消
新程序的执行可能会去渲染游览器, - 接下来,就执行宏任务里的任务,并输出
注意:如果此时还有微任务,宏任务还会被打断
防抖和节流
为什么要把他们俩放在一起呢?当然是因为相似啊!比较学习是一个不错的能加深对知识点认识的方法哦
// 定义一个产生随机色值的函数 节流
function coloring() {
let r=Math.floor(Math.random()*255)
let g=Math.floor(Math.random()*255)
let b=Math.floor(Math.random()*255)
document.body.style.background=`rgba(${r},${g},${b})`
}
//实现节流的函数
function throttle(func,delay) {
let timer;//节流阀:也是实现节流的关键 利用闭包创建一个外层的变量,来控制内层的代码执行与否
return function (){
//context和args都是因为setTimeout所指向的this和接收变量args和外面不同,所以这里是为了优化代码
let context=this
let args=arguments
if(timer)return
timer=setTimeout(() => {
//重定向一下func的this和形参
func.apply(context,args)
timer=null//这里置空,如果用户在规定delay时间内再次点击就会触发上面的if语句,直接不执行下面的代码
console.log('我又变色啦!');
}, delay);
}
}
//监听窗口的变化 实现窗口变化body的背景颜色变化
window.addEventListener('resize',throttle(coloring,2000))
<button id="btn">剁手按钮</button>//html代码
//防抖实现效果:一个事件在n秒能本来只能执行一次 如果不断触发 则刷新计时器重新计时
/**
*这个实例是来防止支付时候误点多下的操作 使用防抖来防止用户多次支付
**/
const btn=document.querySelector('#btn')
//支付功能函数
function payload() {
console.log('已经支付');
}
//防止抖动函数
const debounce=(func,delay)=>{
let timer;//定义一个timer控制内层的执行
return function () {
let context=this
let args=arguments
clearTimeout(timer)//这里如果用户点击事件发生在delay时间内,则会清除上一次的定时器,然后继续执行下面代码 也就是再重新创建一个定时器
timer= setTimeout(function () {
//因为settimeout的this指向的是window 所以需要重新设置this
func.apply(context,args)
// console.log(context);
},delay)
}
}
//绑定事件
btn.addEventListener('click',debounce(payload,1000))
```