Skip to content

Function (函数)

_.after(n, func)

引入版本 0.1.0

_.before 的反向操作;此方法创建一个函数,只有在被调用 n 次或更多次之后,才会真正调用 func

参数

  • n (number): func 执行前需要被调用的次数。
  • func (Function): 要限制执行的函数。

返回

  • (Function): 返回新的受限函数。

示例

js
var saves = ["profile", "settings"];

var done = _.after(saves.length, function () {
  console.log("done saving!");
});

_.forEach(saves, function (type) {
  asyncSave({ type: type, complete: done });
});
// => 当两次 asyncSave 都完成后,输出 'done saving!'。

_.ary(func, [n=func.length])

引入版本 3.0.0

创建一个函数,该函数调用 func 时最多接受 n 个参数,忽略多余的参数。

参数

  • func (Function): 需要限制参数个数的函数。
  • [n=func.length] (number): 参数个数的上限。

返回

  • (Function): 返回新的受限参数个数的函数。

示例

js
_.map(["6", "8", "10"], _.ary(parseInt, 1));
// => [6, 8, 10]

_.before(n, func)

引入版本 3.0.0

创建一个函数,该函数调用 func,并透传 this 绑定和参数。只要调用次数 少于 n 次,func 就会被调用。之后的调用将直接返回最后一次调用 func 的结果。

参数

  • n (number): 超过该调用次数后 func 将不再被调用(即限制执行 n-1 次)。
  • func (Function): 要限制执行的函数。

返回

  • (Function): 返回新的受限函数。

示例

js
jQuery(element).on("click", _.before(5, addContactToList));
// => 允许向列表添加最多 4 个联系人。

_.bind(func, thisArg, [partials])

引入版本 0.1.0

创建一个函数,该函数在调用时会以 thisArgthis 绑定调用 func,并将 partials(部分参数)预先添加到接收到的参数前面。

_.bind.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

注意: 不同于原生的 Function#bind,这个方法不会设置绑定函数的 "length" 属性。

参数

  • func (Function): 要绑定的函数。
  • thisArg (*): functhis 绑定。
  • [partials] (...*): 预先添加的参数。

返回

  • (Function): 返回新的绑定函数。

示例

js
function greet(greeting, punctuation) {
  return greeting + " " + this.user + punctuation;
}

var object = { user: "fred" };

var bound = _.bind(greet, object, "hi");
bound("!");
// => 'hi fred!'

// 使用占位符绑定
var bound = _.bind(greet, object, _, "!");
bound("hi");
// => 'hi fred!'

_.bindKey(object, key, [partials])

引入版本 0.1.0

创建一个函数,该函数在调用时会调用 object[key] 上的方法,并将 partials(部分参数)预先添加到接收到的参数前面。

这个方法与 _.bind 的不同之处在于,它允许绑定函数引用随后可能被重新定义或尚未存在的方法(即延迟绑定)。详情请参考 Peter Michaux 的文章

_.bindKey.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

参数

  • object (Object): 要在其上调用方法的对象。
  • key (string): 方法的键(方法名)。
  • [partials] (...*): 预先添加的参数。

返回

  • (Function): 返回新的绑定函数。

示例

js
var object = {
  user: "fred",
  greet: function (greeting, punctuation) {
    return greeting + " " + this.user + punctuation;
  },
};

var bound = _.bindKey(object, "greet", "hi");
bound("!");
// => 'hi fred!'

// 修改对象上的方法
object.greet = function (greeting, punctuation) {
  return greeting + "ya " + this.user + punctuation;
};

// 绑定的函数会调用新的方法(这一点与 _.bind 不同)
bound("!");
// => 'hiya fred!'

// 使用占位符绑定
var bound = _.bindKey(object, "greet", _, "!");
bound("hi");
// => 'hiya fred!'

_.curry(func, [arity=func.length])

引入版本 2.0.0

创建一个函数,该函数接收 func 的参数。如果接收到的参数数量达到了 arity(默认为 func.length),则调用 func 并返回其结果。否则,返回一个新函数,该函数继续接收剩余的参数,直到参数数量满足要求。

如果 func.length 属性无法准确反映需要的参数个数,可以手动指定 arity

_.curry.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

注意: 这个方法不会设置柯里化函数的 "length" 属性。

参数

  • func (Function): 用来柯里化的函数。
  • [arity=func.length] (number): 需要的参数个数。

返回

  • (Function): 返回新的柯里化函数。

示例

js
var abc = function (a, b, c) {
  return [a, b, c];
};

var curried = _.curry(abc);

curried(1)(2)(3);
// => [1, 2, 3]

curried(1, 2)(3);
// => [1, 2, 3]

curried(1, 2, 3);
// => [1, 2, 3]

// 使用占位符
curried(1)(_, 3)(2);
// => [1, 2, 3]

_.curryRight(func, [arity=func.length])

引入版本 3.0.0

这个方法类似 _.curry。区别在于,它应用参数的方式类似 _.partialRight 而不是 _.partial。(即参数是从右向左组合的)。

_.curryRight.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

注意: 这个方法不会设置柯里化函数的 "length" 属性。

参数

  • func (Function): 用来柯里化的函数。
  • [arity=func.length] (number): 需要的参数个数。

返回

  • (Function): 返回新的柯里化函数。

示例

js
var abc = function (a, b, c) {
  return [a, b, c];
};

var curried = _.curryRight(abc);

curried(3)(2)(1);
// => [1, 2, 3]

curried(2, 3)(1);
// => [1, 2, 3]

curried(1, 2, 3);
// => [1, 2, 3]

// 使用占位符
curried(3)(1, _)(2);
// => [1, 2, 3]

_.debounce(func, [wait=0], [options={}])

引入版本 0.1.0

创建一个防抖动函数。该函数会从上一次被调用后,延迟 wait 毫秒后调用 func

防抖函数提供一个 cancel 方法取消延迟的函数调用,以及 flush 方法立即调用。可以提供 options(选项)在 wait 超时的前沿(leading)和/或后沿(trailing)触发。func 会传入最后一次提供给防抖函数的参数。后续调用的结果是最后一次 func 调用的返回值。

注意: 如果 leadingtrailing 都为 true,则 func 只有在等待超时期间被调用多次时,才会在超时结束(后沿)时被调用。

如果 wait0 并且 leadingfalsefunc 调用将被推迟到下一个事件循环(tick),类似于 setTimeout 设置超时为 0。

查看 David Corbacho 的文章 了解 _.debounce_.throttle 的区别。

参数

  • func (Function): 要防抖的函数。
  • [wait=0] (number): 需要延迟的毫秒数。
  • [options={}] (Object): 选项对象。
  • [options.leading=false] (boolean): 指定在延迟开始前调用。
  • [options.maxWait] (number): 设置 func 允许被延迟的最大值。
  • [options.trailing=true] (boolean): 指定在延迟结束后调用。

返回

  • (Function): 返回新的防抖函数。

示例

js
// 避免在窗口大小变化时进行昂贵的计算。
jQuery(window).on("resize", _.debounce(calculateLayout, 150));

// 点击时调用 `sendMail`,并对后续的调用进行防抖。
jQuery(element).on(
  "click",
  _.debounce(sendMail, 300, {
    leading: true,
    trailing: false,
  })
);

// 确保 `batchLog` 在防抖调用的 1 秒内至少被触发一次。
var debounced = _.debounce(batchLog, 250, { maxWait: 1000 });
var source = new EventSource("/stream");
jQuery(source).on("message", debounced);

// 取消后沿的防抖调用。
jQuery(window).on("popstate", debounced.cancel);

_.defer(func, [args])

引入版本 0.1.0

推迟调用 func,直到当前堆栈清理完毕。调用时,任何附加的参数会传给 func

参数

  • func (Function): 要推迟执行的函数。
  • [args] (...*): 调用 func 时传入的参数。

返回

  • (number): 返回定时器 ID。

示例

js
_.defer(function (text) {
  console.log(text);
}, "deferred");
// => 一毫秒后输出 'deferred'。

_.delay(func, wait, [args])

引入版本 0.1.0

延迟 wait 毫秒后调用 func。任何附加的参数都会在调用时传给 func

参数

  • func (Function): 要延迟执行的函数。
  • wait (number): 延迟调用的毫秒数。
  • [args] (...*): 调用 func 时传入的参数。

返回

  • (number): 返回定时器 ID。

示例

js
_.delay(
  function (text) {
    console.log(text);
  },
  1000,
  "later"
);
// => 一秒后输出 'later'。

_.flip(func)

引入版本 4.0.0

创建一个函数,调用 func 时接收翻转的参数。

参数

  • func (Function): 要翻转参数的函数。

返回

  • (Function): 返回新的翻转函数。

示例

js
var flipped = _.flip(function () {
  return _.toArray(arguments);
});

flipped("a", "b", "c", "d");
// => ['d', 'c', 'b', 'a']

_.memoize(func, [resolver])

引入版本 0.1.0

创建一个会缓存 func 结果的函数。如果提供了 resolver,就用 resolver 的返回值作为缓存 key。如果没有提供 resolver,默认使用函数的第一个参数作为缓存 key。func 在调用时会绑定 this

注意: 缓存会暴露为缓存函数的 cache 属性。可以通过替换 _.memoize.Cache 构造函数来定制缓存的创建,只要新的缓存对象实现了 Map 的接口(clear, delete, get, has, 和 set)。

参数

  • func (Function): 需要缓存输出的函数。
  • [resolver] (Function): 决定缓存 key 的函数。

返回

  • (Function): 返回新的缓存函数。

示例

js
var object = { a: 1, b: 2 };
var other = { c: 3, d: 4 };

var values = _.memoize(_.values);
values(object);
// => [1, 2]

values(other);
// => [3, 4]

object.a = 2;
values(object);
// => [1, 2]
// (因为结果已被缓存,且默认使用第一个参数 object 引用作为 key,引用没变所以返回缓存值)

// 修改结果缓存
values.cache.set(object, ["a", "b"]);
values(object);
// => ['a', 'b']

// 替换 `_.memoize.Cache`
_.memoize.Cache = WeakMap;

_.negate(predicate)

引入版本 3.0.0

创建一个函数,该函数会对 predicate(断言函数)的结果进行取反。predicate 在调用时会绑定 this 并传入创建函数接收到的参数。

参数

  • predicate (Function): 需要取反的断言函数。

返回

  • (Function): 返回一个新的取反函数。

示例

js
function isEven(n) {
  return n % 2 == 0;
}

_.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
// => [1, 3, 5]

_.once(func)

引入版本 0.1.0

创建一个只能调用 func 一次的函数。重复调用该函数会返回第一次调用的结果。func 调用时会绑定 this 并传入创建函数接收到的参数。

参数

  • func (Function): 指定的函数。

返回

  • (Function): 返回新的受限函数。

示例

js
var initialize = _.once(createApplication);
initialize();
initialize();
// => `createApplication` 只会被调用一次

_.overArgs(func, [transforms=[_.identity]])

引入版本 4.0.0

创建一个函数,该函数在调用 func 之前,会先使用对应的 transforms(转换函数)对接收到的参数进行转换。

参数

  • func (Function): 要包裹的函数。
  • [transforms=[_.identity]] (...(Function|Function[])): 用于转换参数的函数数组或参数列表。

返回

  • (Function): 返回新的函数。

示例

js
function doubled(n) {
  return n * 2;
}

function square(n) {
  return n * n;
}

var func = _.overArgs(
  function (x, y) {
    return [x, y];
  },
  [square, doubled]
);

func(9, 3);
// => [81, 6]

func(10, 5);
// => [100, 10]

_.partial(func, [partials])

引入版本 0.2.0

创建一个函数,该函数调用 func,并将 partials(部分参数)预先添加到接收到的参数前面。这个方法类似 _.bind,区别在于它 不会 改变 this 绑定。

_.partial.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

注意: 这个方法不会设置部分应用函数的 "length" 属性。

参数

  • func (Function): 要部分应用参数的函数。
  • [partials] (...*): 预先添加的参数。

返回

  • (Function): 返回新的部分应用函数。

示例

js
function greet(greeting, name) {
  return greeting + " " + name;
}

var sayHelloTo = _.partial(greet, "hello");
sayHelloTo("fred");
// => 'hello fred'

// 使用占位符进行部分应用
var greetFred = _.partial(greet, _, "fred");
greetFred("hi");
// => 'hi fred'

_.partialRight(func, [partials])

引入版本 1.0.0

这个方法类似 _.partial,区别在于它会将 partials(部分应用参数)追加 到函数接收到的参数列表的 末尾

_.partialRight.placeholder 的值(在整体构建中默认为 _)可以用作部分应用参数的占位符。

注意: 这个方法不会设置部分应用函数的 "length" 属性。

参数

  • func (Function): 要部分应用参数的函数。
  • [partials] (...*): 要部分应用的参数。

返回

  • (Function): 返回新的部分应用函数。

示例

js
function greet(greeting, name) {
  return greeting + " " + name;
}

var greetFred = _.partialRight(greet, "fred");
greetFred("hi");
// => 'hi fred'

// 使用占位符进行部分应用
var sayHelloTo = _.partialRight(greet, "hello", _);
sayHelloTo("fred");
// => 'hello fred'

_.rearg(func, indexes)

引入版本 3.0.0

创建一个函数,该函数调用 func,并根据指定的 indexes(索引)重新排列参数。 具体来说,indexes 中的第一个索引对应的值会作为第一个参数传给 func,第二个索引对应的值作为第二个参数,以此类推。

参数

  • func (Function): 要重新排列参数的函数。
  • indexes (...(number|number[])): 排列后的参数索引。

返回

  • (Function): 返回新的函数。

示例

js
var rearged = _.rearg(
  function (a, b, c) {
    return [a, b, c];
  },
  [2, 0, 1]
);

rearged("b", "c", "a");
// => ['a', 'b', 'c']

_.rest(func, [start=func.length-1])

引入版本 4.0.0

创建一个函数,调用 func 时,this 绑定指向创建的函数,并将从 start 位置开始的所有后续参数收集为一个数组传递给 func

注意: 此方法基于 rest parameter(剩余参数)。

参数

  • func (Function): 要应用剩余参数的函数。
  • [start=func.length-1] (number): 剩余参数的起始位置(默认为最后一个参数的位置)。

返回

  • (Function): 返回新的函数。

示例

js
var say = _.rest(function (what, names) {
  return (
    what +
    " " +
    _.initial(names).join(", ") +
    (_.size(names) > 1 ? ", & " : "") +
    _.last(names)
  );
});

say("hello", "fred", "barney", "pebbles");
// => 'hello fred, barney, & pebbles'

_.spread(func, [start=0])

引入版本 3.2.0

创建一个函数,该函数调用 functhis 绑定指向创建的函数,并将接收到的数组参数 展开func 的独立参数(类似 Function#apply)。

注意: 此方法基于 spread operator(展开语法)。

参数

  • func (Function): 要应用展开参数的函数。
  • [start=0] (number): 展开参数的起始位置。

返回

  • (Function): 返回新的函数。

示例

js
var say = _.spread(function (who, what) {
  return who + " says " + what;
});

say(["fred", "hello"]);
// => 'fred says hello'

var numbers = Promise.all([Promise.resolve(40), Promise.resolve(36)]);

numbers.then(
  _.spread(function (x, y) {
    return x + y;
  })
);
// => 一个解析为 76 的 Promise

_.throttle(func, [wait=0], [options={}])

引入版本 0.1.0

创建一个节流函数,在 wait 毫秒内最多执行 func 一次。

该节流函数提供 cancel 方法取消延迟的函数调用,以及 flush 方法立即调用。可以提供 options(选项)在 wait 超时的前沿(leading)和/或后沿(trailing)触发。func 会传入最后一次提供给节流函数的参数。

注意: 如果 leadingtrailing 都为 true,则 func 只有在等待超时期间被调用多次时,才会在超时结束(后沿)时被调用。

如果 wait0 并且 leadingfalsefunc 调用将被推迟到下一个事件循环(tick),类似于 setTimeout 设置超时为 0。

查看 David Corbacho 的文章 了解 _.debounce_.throttle 的区别。

参数

  • func (Function): 要节流的函数。
  • [wait=0] (number): 需要节流的毫秒数。
  • [options={}] (Object): 选项对象。
  • [options.leading=true] (boolean): 指定调用在节流开始前。
  • [options.trailing=true] (boolean): 指定调用在节流结束后。

返回

  • (Function): 返回新的节流函数。

示例

js
// 避免在滚动时过分频繁地更新定位。
jQuery(window).on("scroll", _.throttle(updatePosition, 100));

// 点击后调用 `renewToken`,但 5 分钟内最多一次。
var throttled = _.throttle(renewToken, 300000, { trailing: false });
jQuery(element).on("click", throttled);

// 取消后沿的节流调用。
jQuery(window).on("popstate", throttled.cancel);

_.unary(func)

引入版本 4.0.0

创建一个函数,该函数调用 func 时最多接受一个参数,忽略任何额外的参数。

参数

  • func (Function): 需要限制参数个数的函数。

返回

  • (Function): 返回新的受限函数。

示例

js
_.map(["6", "8", "10"], _.unary(parseInt));
// => [6, 8, 10]

_.wrap(value, [wrapper=identity])

引入版本 0.1.0

创建一个函数。该函数在调用时,会将 value 作为第一个参数传给 wrapper(包装函数)。任何传递给这个新函数的额外参数,都会被追加到传给 wrapper 的参数列表中。调用 wrapper 时,this 绑定会指向这个新创建的函数。

参数

  • value (*): 要被包装的值。
  • [wrapper=identity] (Function): 包装函数。

返回

  • (Function): 返回新的函数。

示例

js
var p = _.wrap(_.escape, function (func, text) {
  return "<p>" + func(text) + "</p>";
});

p("fred, barney, & pebbles");
// => '<p>fred, barney, &amp; pebbles</p>'