匿名函数内的this不是指向window吗
常用的定时器手写防抖节流函数
function debounce(fn, delay) {
var timer;
return function () {
var _this = this; // 在匿名函数内取了this
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn.apply(_this, args); // 将this传给fn
}, delay);
};
}
function throttle(fn, delay) {
console.debug('throttle this', this);
let canUse = true;
return function() {
if (canUse) {
fn.apply(this, arguments); // 将匿名函数的this传给fn
canUse = false;
setTimeout(() => (canUse = true), delay);
}
};
}
这两个函数,都将匿名函数的this,传递给了fn
那么问题来了:
这里传this,是匿名函数内部的this。
匿名函数没有绑定到任何对象,内部的this应该是指向window吧?
将window对象绑定给fn? 这好像没必要吧?
而且,这里不是想把throttle的this绑定给fn吗,那为什么不在匿名函数外取this呢?
防抖节流的this写错地方了吗?
为了探究这个问题,我以throttle函数为例,给各个函数绑定了不同对象。
给各函数绑定对象,查看this输出结果
const a = {};
const b = {};
a.throttleInA = function throttle(fn, delay) {
console.debug('throttle this', this);
let canUse = true;
return function() {
console.debug('匿名函数 this', this);
//作为返回的匿名函数,指向调用该事件函数 谁调用,这个this指谁
if (canUse) {
fn.apply(this, arguments);
canUse = false;
setTimeout(() => (canUse = true), delay);
}
};
};
function fn() {
console.debug('fn this', this);
}
b.throttleFuncB = a.throttleInA(fn);
b.throttleFuncB();
在以上代码中,
throttle函数绑定了对象a,为 a.throttleInA
调用函数绑定对象b,为b.throttleFuncB
传入的函数fn,将会打印出fn内部的this,即匿名函数内给fn绑定的this
按照之前的分析,
throttle this 打印出来的this是指向对象a的
匿名函数的this 指向window
绑定了匿名函数this的fn 也指向window
最终打印结果如下:
可以发现,
throttle函数的this,指向的是对象a,意料之中
匿名函数内部的this,指向的是对象b,不是对象a,也不是window
绑定了匿名函数this的fn,指向对象b
怎么回事?
匿名函数的this,指向了调用它的对象
该匿名函数,作为返回值,返回给了对象b。
因此,匿名函数内部的this,也指向了对象b
也就是说,给fn绑定的this,既不是window,也不是throttle函数的对象a
而是调用该节流函数的对象b
这样,对象调用防抖节流时,fn可以获取对象的this