繁体   English   中英

写去抖时,fn.apply(context,args)有什么意义?

[英]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(); 

this1this2this3不一样呢? fn.apply()的意图是什么? 在这种情况下,为什么我们选择fn.apply(this2)而不是fn()fn.apply(this1)fn.apply(this3)

  1. 保留去抖动功能的上下文(此值)。
  2. 处理未知数量的参数。

1。

该函数可能会附加到一个对象,因此在调用该函数时,上下文应该是该对象。 这得到重视这样的目标函数没有被fn ,它是通过返回的匿名函数debounce 因此,在调用fn我们必须使用callapply在与该匿名函数相同的上下文中进行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 ,如果执行,这意味着debouncedFnfunctionX将被执行。 现在,当传递n的参数数目debouncedFn ,那些可以在检索functionX经由保留关键字arguments 最终,您希望将参数提供给fn ,因此要将这些参数传递给fn我们必须使用apply() 有关更多信息,请单击此链接

this1, this2, this3: debounce总是在全球执行的,这就是为什么它的背景是windowfunctionX()可以连接到一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM