对闭包的理解以及它的使用场景
创建闭包最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问当前函数的局部变量
优点
- 加强对变量的封装性,达到对变量的保护作用
- 创建全局私有变量,避免变量的全局污染
缺点
- 对内存以及性能消耗比较大,创建的变量不能被回收(可以在不需要使用变量时候设置为null)
对作用域、作用域链的理解
作用域指一个变量和函数的可访问范围,分全局作用域和局部作用域
全局作用域
变量和函数可以在任意地方访问
局部作用域
函数内声明的变量,只能在函数内部访问变量和函数,当函数执行完毕,里面的变量和函数就会销毁掉
作用域链
在当前作用域中找指定的变量或者函数,没有找到就会往外层继续寻找,直到外层的全局变量,这个查找的过程叫做作用域链
call()、bind()、apply()的区别
- 都能改变this的指向
- call、bind传参的是对象,apply是数组
- call、apply在调用后会立即执行函数,bind需要在改变this后返回一个函数,不会立即执行,需要手动调用
- call、apply修改this指向的性质不同、他们只能修改一次,在下次调用函数后,指向还是函数原状态,但是bind不一样他返回了一个新的函数,修改的不是原来的函数,他的指向是永久性的
浏览器的垃圾回收机制(V8)
js代码运行时,需要分配内存空间来存储变量和值,在变量不参加运行时候,就需要系统回收他,以免占用内存空间,如果不及时清理,会造成系统不流畅,内存的溢出,这时候就需要垃圾回收机制去处理这种问题!
防抖debounce
在规定的时间后执行,如果触发重新计时,比如无论在1秒内我触发oninput时间多少次我只执行一次oninput。
使用场景
- 频繁点击操作的按钮,避免用户多次点击
- 鼠标移动mousedown等
实现原理就是使用定时器
// 防抖debounce函数
export function debounce(fn, wait = 300) {
let timer = null
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}