防抖,在一定时间内,多次点击只有一次有效,节流,只要是事件不停止就不会执行。函数也很简单,两者一个不同就是一个清除定时器,一个直接返回。
先直接上代码:
function throttle(fn, time = 500){
let timer = null;
return function(){
let context = this;
let args = arguments;
if(timer){
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, time)
}
}
function debounce(fn, time = 500){
let timer = null;
return function(){
let context = this;
let args = arguments;
if(timer){
return
}
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, time)
}
}
let vm = new Vue({
el: '#app',
data(){
return {
isVm: 'isVm'
}
},
mounted(){
},
methods:{
testThrottle: throttle(function(a){
console.log('is throttle', a, this)
}, 1000),
testDebounce: debounce(function(a){
console.log('is debounce', a, this);
}, 1000),
}
})
测试得到的效果,节流的函数,在你一直点击的情况下是不会执行,等你停止点击一秒后执行。防抖在你一直点击的情况下,每隔一秒就会执行一次。
vue方法的写法:
test(){}
test: function () {}
其实就是ES6函数的简写和正常的写法,我们防抖节流返回一个函数,所以直接调用然后通过回调执行。这边有几点要注意:
一个是防抖节流函数return的函数不能是箭头函数,否则this指向就会变成window
另一个就是使用的时候debounce(throttl)包裹的函数也不能是箭头函数,要function,否则this的指向也会指向window。
至于你用apply还是call都随意,用call就用展开符…args传参就行。
一开始我想都用箭头函数,结果this指向一直是window,箭头函数没有this,也不能用call、apply、bind。
MDN上面对this的解释:在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。
我的理解就是,函数的this是谁调用就指向谁,手写call、apply、bind就是用的这个原理,而箭头函数理解成声明的时候就绑定this,声明的时候就指向最外层不是箭头函数的函数,比如下面的例子:
箭头函数:
function test1(fn) {
console.log('test1', this)//test1 {}
fn();
}
test1.call({}, () => {
console.log('callback', this)//callback window
})
function函数:
function test1(fn) {
console.log('test1', this)//test1 {}
fn();
}
test1.call({}, function () {
console.log('callback', this)//callback window
})
无论是使用function还是箭头函数,回调函数的this都是window。
function test1(fn) {
console.log('test1', this)//test1 {}
fn();
}
function test2() {
test1.call({}, () => {
console.log('callback', this)//callback {a: 10}
})
}
test2.apply({a: 10})
这边使用箭头函数的时候,回调函数的this就会是声明的时候的test2的this,如果我不用apply:
function test1(fn) {
console.log('test1', this)//test1 {}
fn();
}
function test2() {
test1.call({}, () => {
console.log('callback', this)//callback window
})
}
test2()
回调函数的this指向的也是test2的this,这次是window。如果用function,test2有没有用apply,回调函数的this都是window:
function test1(fn) {
console.log('test1', this)//test1 {}
fn();
}
function test2() {
test1.call({}, function(){
console.log('callback', this)//callback window
})
}
test2.apply({a: 10})
验证了MDN上面说的:函数的调用方式决定了 this 的值(运行时绑定),箭头函数不提供自身的 this 绑定(this 的值将保持为闭合词法上下文的值)。只不过箭头函数的this会因为闭合词法上下文的值的this的改变而改变,有点像对象的浅拷贝。
欢迎关注订阅号 coding个人笔记