[英]When writing a debounce, what is the point of fn.apply(context, args)?
function debounce(fn, delay) { let timer = null; // this1 return function() { let context = this, args = arguments; // context = this2 clearTimeout(timer); timer = setTimeout(function() { // this3 fn.apply(context, args); }, delay); } } var debouncedFn = debounce(function() { console.log('hi'); }, 50); debouncedFn();
是this1
, this2
和this3
不一样呢? fn.apply()
的意图是什么? 在这种情况下,为什么我们选择fn.apply(this2)
而不是fn()
或fn.apply(this1)
或fn.apply(this3)
?
1。
该函数可能会附加到一个对象,因此在调用该函数时,上下文应该是该对象。 这得到重视这样的目标函数没有被fn
,它是通过返回的匿名函数debounce
。 因此,在调用fn
我们必须使用call
或apply
在与该匿名函数相同的上下文中进行call
。
2。
实际调用的函数是匿名函数,该函数将在一段时间后调用fn
。 由于我们不知道fn
有多少个参数,我们只需要使用arguments
对象和aplly
call
匿名函数调用的所有参数,就可以调用它(这里将不使用call
,因为它需要单独的参数而不是分组的-数组中的参数)。
thisN问题:
不,他们不一样。
由于debounce
未附加到任何对象,因此this1
将成为window
。
this2
可以是window
,也可以是其他任何东西,具体取决于您如何调用debounce
:
var f = debounde(someFn, 100); // this2 is window
var obj = {};
obj.f = debounce(someFn, 100); // this2 is obj
由于此 , this3
也是window
。
让我们为函数添加一些名称
function debounce(fn, delay) {
let timer = null;
return function functionX() {
let context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function functionY() {
fn.apply(context, args);
}, delay);
}
}
var debouncedFn = debounce(function functionZ() {
console.log('hi');
}, 50);
debouncedFn();
为什么.apply()
这里debouncedFn
持有的参考functionX
,如果执行,这意味着debouncedFn
, functionX
将被执行。 现在,当传递n
的参数数目debouncedFn
,那些可以在检索functionX
经由保留关键字arguments
。 最终,您希望将参数提供给fn
,因此要将这些参数传递给fn
我们必须使用apply()
。 有关更多信息,请单击此链接 。
this1, this2, this3:
debounce
总是在全球执行的,这就是为什么它的背景是window
, functionX()
可以连接到一个object
,这就是为什么上下文functionX()
将物体在你把debouncedFn()
和由于全局执行,因此setTimeout
上下文再次成为window
。 请参阅以下示例,以更好地了解上下文。
function debounce(fn, delay) { let timer = null; console.log('this1', this.name); return function() { let context = this, args = arguments; console.log('this2', this.name); clearTimeout(timer); timer = setTimeout(function() { console.log('this3', this.name); fn.apply(context, args); }, delay); } } var person = { name: 'John', age: 23, getName: debounce(function() { console.log('hi'); }, 50) } person.getName(); person.getName();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.