为什么VueUse里的useIntersectionObserver函数的回调函数内部可以调用stop()方法?
前端小菜鸟一只,今天遇到了个大难题。业务需求是利用VueUse的useIntersectionObserver函数实现图片资源懒加载,但我比较困惑的地方是useIntersectionObserver函数的第二个参数是一个回调函数,为什么可以在这个回调函数里调用 stop() 来停止监听呢?
我困惑的地方在于:赋值语句从右到左进行,先得到等号右边的结果再赋值给左边,调用stop()的时候等号左边还没有解构出 stop 这个方法呀。我在解构时尝试重新命名为 abc,回调函数内部调用 abc()程序仍正常运作,说明回调函数内调用的就是等号左边解构出的结果。虽然业务功能可以实现,但我不明白为什么可以这样写,希望好心人能指点一下
我可以理解下面这种,返回值赋值给stop后调用stop()函数。(图片来自VueUse官网)
回答:
简单构建一下模拟的代码,就会发现,并不是所有情况下,都可以这样用。
比如下面的代码中,如果你把 setTimeout 换成同步的方式去调用(直接调用 cb),那就会出现两种情况。
- 1、如果下面的解构获取是使用的 const,那就会报 “不能在变量初始化之前进行使用”
- 2、如果下面的解构获取是使用的 var,那就会报 “abc 不是一个函数”
重要的点就在于,在执行这个 abc
时,这个变量是否已经拿到了值。
当使用同步执行的时候,实际上要走到后面的 return 才能把这里的 stop 给出去,这时候才有 stop 函数。
而当这个回调函数作为异步执行时,就不一样了,异步时,这里的函数已经执行完了,外面已经拿到返回值并解构赋值给了 abc。
在调用时,就会跟随其声明的域开始向上查找,找到对应的方法进行调用。
!(function () { function foo (el, cb) {
setTimeout(cb) // 重要
return {
stop () {
console.log('stop')
},
}
}
const { stop: abc } = foo('#app', () => {
console.log(this)
abc()
})
})()
回答:
就是基础的变量作用域的问题,跟 IntersectionObserver 无关,跟 VueUse 也无关。
你在内部作用域里访问 abc()
,会先从当前作用域开始找,没找到有这个变量,就会向上层作用域找,直到全局作用域为止。要是中间找到了,那就是它了;要是到最后也没找到,在严格模式下那就抛变量未定义的异常了。
const { foo: bar } = (function () { setTimeout(() => bar(), 1000);
return {
foo: () => console.log('bingo!')
};
})();
如果你能明白这段代码里内部是怎么访问到 bar()
的,也就能明白前面是怎么访问到 abc()
的了。
以上是 为什么VueUse里的useIntersectionObserver函数的回调函数内部可以调用stop()方法? 的全部内容, 来源链接: utcz.com/p/934739.html