因为你调用的原始函数
this[act].apply(this, data)
使用this,我假设您是从对象的方法中调用它。问题是,如何从这里到那里获得this?许多高阶函数被设计为使用与调用它们自身相同的this 调用底层函数,使用以下类型的骨架:
function higher_order_function(fn) {
return function() {
return fn.apply(this, arguments);
};
}
这意味着,如果我有一个带有方法的对象
var obj = {
val: 42,
print: function() { console.log(this.val); }
}
然后我想改造print函数:
obj.newPrint = higher_order_function(obj.print);
我现在可以调用obj.newPrint,在下面,this 将用于调用print,一切正常。
对于此类事情还有其他设计,包括显式传递上下文 (this) 并将它们作为单独的参数提供给函数,但上述方法通常更简洁且“有效”。
这就是_.throttle 的工作原理。如果你查看源代码,你会看到它在做类似的事情
return function() {
...
context = this;
args = arguments;
...
result = func.apply(context, args);
};
这意味着,要以节流方式调用您的代码,您需要做的就是安排使用this 调用它。
假设您调用的原始代码在一个名为act 的函数中。
var obj = {
act: function(act) {
this[act].apply(this, data);
}
};
制作act 的节流版本(这里,我们直接在对象上制作;您可以通过将其放在原型上来完成类似的事情,见下文):
obj.throttledAct = _.throttle(obj.act);
然后简单地调用
obj.throttledAct('act1')
如果您使用原型编程:
Foo.prototype.func = function(act) { this[act].apply(this, data) };
然后您可以将节流版本放在原型上:
Foo.prototype.throttledFunc = _.throttle(Foo.prototype.func);
一切都会按预期进行。
如果您出于某种原因想要创建一个独立版本的节流函数,而不是将其放入对象或原型中:
var throttledFunc = _.throttled(func);
然后您可以使用call 或apply 调用它来强制this 的值:
throttledFunc.call(obj, 'act1`);
但是在任何一种情况下,参数'act1' 是如何传递给底层函数的。这也可以通过_.throttle 的实现中的行来完成
result = func.apply(context, args);
这里args 是传递给_.throttle 构造函数的参数,apply 用于将它们与this 一起传递给底层函数。请注意,_.throttle 本身也需要额外的参数来传递给底层函数,但这是“烧录它们”而不是让它们在每次调用节流函数时都被指定。
你的尝试
_.throttle(/* different permutations of combined args */)
_.throttle.apply(/* same */)
_.throttle.apply(myArgs)(throttleArgs)
_.throttle(throttleArgs).apply(myArgs)
所有这些都面临着同样的问题,那就是_.throttle 必须传递一个函数 进行限制,并返回一个函数,然后调用该函数以获得限制行为。最后一个可能是最接近的,假设 throttleArgs 是要限制的函数,而 myArgs 实际上是 this, myArgs。