vue中封装节流不改变this指向,求指教

vue中封装节流不改变this指向,求指教

我在vue中封装了一个节流,使用时直接传递需要调用的方法过去,节流功能可以实现,但我在网上看到别人写的节流发现他们都在函数中使用了apply来调用,并且改变了this指向,让我很不解,请大佬为我解惑

//节流

export function throttle(callback, wait = 50) {

let timer = null

let flag = true

return function () {

if (flag) {

timer = setTimeout(() => {

callback()

flag = true

clearTimeout(timer)

timer = null

}, wait)

}

flag = false

}

}

在使用的地方

    methods: {

resize() { //这个resize是我自己写的方法

this.$refs.alarmNumberBox.initWH();

this.$refs.alarmTrendBox.initWH();

this.$refs.currentQuantityBox.initWH();

this.$refs.alarmNumber.screenAdapter();

this.$refs.alarmTrend.screenAdapter();

this.$refs.alarmToday.screenAdapter();

}

},

绑定节流处

 activated() {

//保存函数

const resize = throttle(this.resize, 50);

//挂载

window.addEventListener("resize", resize);

},

我这种写法经测试不需要apply来改变this,可以实现功能,但总感觉哪里不太好,大佬有空的话,请帮我看看


回答:

别人写的是通用的,比如原本的代码是:

{

// ...

resize: function(){

this.XXXX...

}

}

有一天老板突然说要加个节流,别人引入 throttle 函数把它包装一下就能搞定:

{

// ...

resize: throttle(function(){

this.XXXX...

})

}

可以看到这里是直接在定义 resize 的地方进行修改,而不用关心它何时注册为回调函数、何时调用,而你的写法需要从注册resize回调函数的地方去修改。

试想一下,假如你写的不是一个只需注册一次的函数,而是需要在很多地方调用,你是不是要在这些调用的地方一个个去节流(而别人仅仅是在定义函数的地方节流)?


回答:

防抖 和 节流是两种方法,防抖的意义在与 在限制时间内函数只执行以此,也就每次调用在未达到时间间隔时,定时都会重新开始,通俗点说每次指定都小于wait time那么防抖函数永远都不会执行,所以要绑定this

节流:只要时间达到就会执行,也就是说时间达到wait time节流函数就会被执行

你现在用的是节流方式


回答:

人家写的是通用的,你写的不能脱离vue。
这里调用callback就已经丢失了原本的this,

timer = setTimeout(() => {

callback()

}, wait)

因此当执行this.$refs.alarmNumberBox.initWH();时就会报错了,$refs是undefined。

你这里没有报错纯属偶然,因为vue替你把this绑定上去了。

Object.defineProperty(ctx, key, {

value: methodHandler.bind(publicThis),

configurable: true,

enumerable: true,

writable: true

});

下面给一个更完整的例子:

var opt = {

name:'opt',

methods:{

resize(){

console.log(this.name)

}

},

actived(){

const resize = throttle(this.resize, 50);

window.addEventListener("resize", resize);

}

}

class A {

constructor(opt){

this.name = opt.name;

this.resize = opt.methods.resize.bind(this);

this.actived = opt.actived.bind(this)

}

}

var a = new A(opt);

a.actived()

这样子也能正常运行,因为a.actived这个函数已经绑定了this;但如果constructor中没有做bind的操作,那么就会得到预期外的结果。

以上是 vue中封装节流不改变this指向,求指教 的全部内容, 来源链接: utcz.com/p/937377.html

回到顶部