与函数有关的函数(Function (uh, ahem) Functions)

优质
小牛编辑
137浏览
2023-12-01

bind_.bind(function, object, *arguments)
绑定函数 function 到对象 object 上, 也就是无论何时调用函数, 函数里的 this 都指向这个 object.任意可选参数 arguments 可以传递给函数 function , 可以填充函数所需要的参数,这也被称为 partial application。对于没有结合上下文的partial application绑定,请使用partial
(注:partial application翻译成“部分应用”或者“偏函数应用”。partial application可以被描述为一个函数,它接受一定数目的参数,绑定值到一个或多个这些参数,并返回一个新的函数,这个返回函数只接受剩余未绑定值的参数。参见:http://en.wikipedia.org/wiki/Partial_application。)。

var func = function(greeting){ return greeting + ': ' + this.name };
func = _.bind(func, {name: 'moe'}, 'hi');
func();
=> 'hi: moe'

bindAll_.bindAll(object, *methodNames)
methodNames参数指定的一些方法绑定到object上,这些方法就会在对象的上下文环境中执行。绑定函数用作事件处理函数时非常便利,否则函数被调用时this一点用也没有。methodNames参数是必须的。

var buttonView = {
  label  : 'underscore',
  onClick: function(){ alert('clicked: ' + this.label); },
  onHover: function(){ console.log('hovering: ' + this.label); }
};
_.bindAll(buttonView, 'onClick', 'onHover');
// When the button is clicked, this.label will have the correct value.
jQuery('#underscore_button').on('click', buttonView.onClick);

partial_.partial(function, *arguments)
局部应用一个函数填充在任意个数的 arguments改变其动态this值。和bind方法很相近。你可以传递_arguments列表来指定一个不预先填充,但在调用时提供的参数。

var subtract = function(a, b) { return b - a; };
sub5 = _.partial(subtract, 5);
sub5(20);
=> 15

// Using a placeholder
subFrom20 = _.partial(subtract, _, 20);
subFrom20(5);
=> 15

memoize_.memoize(function, [hashFunction])
Memoizes方法可以缓存某函数的计算结果。对于耗时较长的计算是很有帮助的。如果传递了 hashFunction 参数,就用 hashFunction 的返回值作为key存储函数的计算结果。hashFunction 默认使用function的第一个参数作为key。memoized值的缓存可作为返回函数的cache属性。

var fibonacci = _.memoize(function(n) {
  return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});

delay_.delay(function, wait, *arguments)
类似setTimeout,等待wait毫秒后调用function。如果传递可选的参数arguments,当函数function执行时, arguments 会作为参数传入。

var log = _.bind(console.log, console);
_.delay(log, 1000, 'logged later');
=> 'logged later' // Appears after one second.

defer_.defer(function, *arguments)
延迟调用function直到当前调用栈清空为止,类似使用延时为0的setTimeout方法。对于执行开销大的计算和无阻塞UI线程的HTML渲染时候非常有用。 如果传递arguments参数,当函数function执行时, arguments 会作为参数传入。

_.defer(function(){ alert('deferred'); });
// Returns from the function before the alert runs.

throttle_.throttle(function, wait, [options])
创建并返回一个像节流阀一样的函数,当重复调用函数的时候,至少每隔 wait毫秒调用一次该函数。对于想控制一些触发频率较高的事件有帮助。(注:详见:javascript函数的throttle和debounce,感谢 @澳利澳先生 的翻译建议)

默认情况下,throttle将在你调用的第一时间尽快执行这个function,并且,如果你在wait周期内调用任意次数的函数,都将尽快的被覆盖。如果你想禁用第一次首先执行的话,传递{leading: false},还有如果你想禁用最后一次执行的话,传递{trailing: false}

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

如果需要取消预定的 throttle ,可以在 throttle 函数上调用 .cancel()

debounce_.debounce(function, wait, [immediate])
返回 function 函数的防反跳版本, 将延迟函数的执行(真正的执行)在函数最后一次调用时刻的 wait 毫秒之后. 对于必须在一些输入(多是一些用户操作)停止到达之后执行的行为有帮助。 例如: 渲染一个Markdown格式的评论预览, 当窗口停止改变大小之后重新计算布局, 等等.

wait 间隔结束时,将使用最近传递给 debounced(去抖动)函数的参数调用该函数。

传参 immediatetruedebounce会在 wait 时间间隔的开始调用这个函数 。(注:并且在 waite 的时间之内,不会再次调用。)在类似不小心点了提交按钮两下而提交了两次的情况下很有用。 (感谢 @ProgramKid 的翻译建议)

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

如果需要取消预定的 debounce ,可以在 debounce 函数上调用 .cancel()

once_.once(function)
创建一个只能调用一次的函数。重复调用改进的方法也没有效果,只会返回第一次执行时的结果。 作为初始化函数使用时非常有用, 不用再设一个boolean值来检查是否已经初始化完成.

var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.

after_.after(count, function)
创建一个函数, 只有在运行了 count 次之后才有效果. 在处理同组异步请求返回结果时, 如果你要确保同组里所有异步请求完成之后才 执行这个函数, 这将非常有用。

var renderNotes = _.after(notes.length, render);
_.each(notes, function(note) {
  note.asyncSave({success: renderNotes});
});
// renderNotes is run once, after all notes have saved.

before_.before(count, function)
创建一个函数,调用不超过count 次。 当count已经达到时,最后一个函数调用的结果将被记住并返回。

var monthlyMeeting = _.before(3, askForRaise);
monthlyMeeting();
monthlyMeeting();
monthlyMeeting();
// the result of any subsequent calls is the same as the second call

wrap_.wrap(function, wrapper)
将第一个函数 function 封装到函数 wrapper 里面, 并把函数 function 作为第一个参数传给 wrapper. 这样可以让 wrapperfunction 运行之前和之后 执行代码, 调整参数然后附有条件地执行。

var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
  return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'

negate_.negate(predicate)
返回一个新的predicate函数的否定版本。

var isFalsy = _.negate(Boolean);
_.find([-2, -1, 0, 1, 2], isFalsy);
=> 0

compose_.compose(*functions)
返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))

var greet    = function(name){ return "hi: " + name; };
var exclaim  = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'

restArguments_.restArguments(function, [startIndex])
返回 function 的一个版本,该函数版本在调用时接收来自 startIndex 的所有参数,并将其收集到单个数组中。 如果未传递显式的 startIndex ,则将通过查看 function 本身的参数数来确定。 与 ES6 的 rest参数语法类似。

var raceResults = _.restArguments(function(gold, silver, bronze, everyoneElse) {
  _.each(everyoneElse, sendConsolations);
});

raceResults("Dopey", "Grumpy", "Happy", "Sneezy", "Bashful", "Sleepy", "Doc");