与函数有关的函数(Function (uh, ahem) Functions)
bind
_.bind(function, object, *arguments)
绑定函数 function 到对象 object 上, 也就是无论何时调用函数, 函数里的 this 都指向这个 object.任意可选参数 arguments 可以传递给函数 function , 可以填充函数所需要的参数,这也被称为 partial application。对于没有结合上下文的partial application绑定,请使用partial。
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毫秒调用一次该函数。对于想控制一些触发频率较高的事件有帮助。默认情况下,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(去抖动)函数的参数调用该函数。传参 immediate 为 true, debounce会在 wait 时间间隔的开始调用这个函数 。(愚人码头注:并且在 waite 的时间之内,不会再次调用。)在类似不小心点了提交按钮两下而提交了两次的情况下很有用。
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. 这样可以让 wrapper 在 function 运行之前和之后 执行代码, 调整参数然后附有条件地执行。
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");
对象函数(Object Functions)
keys
_.keys(object)
检索object拥有的所有可枚举属性的名称。
_.keys({one: 1, two: 2, three: 3});
=> ["one", "two", "three"]
allKeys
_.allKeys(object)
检索object拥有的和继承的所有属性的名称。
function Stooge(name) { this.name = name; } Stooge.prototype.silly = true; _.allKeys(new Stooge("Moe")); => ["name", "silly"]
values
_.values(object)
返回object对象所有的属性值。
_.values({one: 1, two: 2, three: 3});
=> [1, 2, 3]
mapObject
_.mapObject(object, iteratee, [context])
它类似于map,但是这用于对象。转换每个属性的值。
_.mapObject({start: 5, end: 12}, function(val, key) { return val + 5; }); => {start: 10, end: 17}
pairs
_.pairs(object)
把一个对象转变为一个[key, value]形式的数组。object 逆向函数。
_.pairs({one: 1, two: 2, three: 3});
=> [["one", 1], ["two", 2], ["three", 3]]
invert
_.invert(object)
返回一个object副本,使其键(keys)和值(values)对换。对于这个操作,必须确保object里所有的值都是唯一的且可以序列号成字符串.
_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};
create
_.create(prototype, props)
创建具有给定原型的新对象,可选附加props 作为 own的属性。基本上,和Object.create一样,但是没有所有的属性描述符。
var moe = _.create(Stooge.prototype, {name: "Moe"});
functions
_.functions(object) Alias: methods
返回一个对象里所有的方法名, 而且是已经排序的 — 也就是说, 对象里每个方法(属性值是一个函数)的名称.
_.functions(_);
=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
findKey
_.findKey(object, predicate, [context])
类似于_.findIndex ,但用于对象中的 key(键)。返回通过predicate 真值测试的 key ,否则返回 undefined 。 predicate 通过 iteratee 进行转换,以简化速记语法。
extend
_.extend(destination, *sources)
将source对象中的所有属性简单地覆盖到destination对象上,并且返回 destination 对象. 复制是按顺序的, 所以后面的对象属性会把前面的对象属性覆盖掉(如果有重复)。
_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}
extendOwn
_.extendOwn(destination, *sources) Alias: assign
类似于 extend, 但只复制自己的属性覆盖到目标对象。(愚人码头注:不包括继承过来的属性)。
pick
_.pick(object, *keys)
返回一个object副本,只过滤出keys(有效的键组成的数组)参数指定的属性值。或者接受一个判断函数,指定挑选哪个key。
_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age'); => {name: 'moe', age: 50} _.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) { return _.isNumber(value); }); => {age: 50}
omit
_.omit(object, *keys)
返回一个object副本,只过滤出除去keys(有效的键组成的数组)参数指定的属性值。 或者接受一个判断函数,指定忽略哪个key。
_.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid'); => {name: 'moe', age: 50} _.omit({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) { return _.isNumber(value); }); => {name: 'moe', userid: 'moe1'}
defaults
_.defaults(object, *defaults)
用defaults对象填充object 中的undefined属性。 并且返回这个object。一旦这个属性被填充,再使用defaults方法将不会有任何效果。(感谢@一任风月忆秋年的拍砖)
var iceCream = {flavor: "chocolate"}; _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"}); => {flavor: "chocolate", sprinkles: "lots"}
clone
_.clone(object)
创建 一个浅复制(浅拷贝)的克隆object。任何嵌套的对象或数组都通过引用拷贝,不会复制。
_.clone({name: 'moe'});
=> {name: 'moe'};
tap
_.tap(object, interceptor)
用 object作为参数来调用函数interceptor,然后返回object。这种方法的主要意图是作为函数链式调用 的一环, 为了对此对象执行操作并返回对象本身。
_.chain([1,2,3,200]) .filter(function(num) { return num % 2 == 0; }) .tap(alert) .map(function(num) { return num * num }) .value(); => // [2, 200] (alerted) => [4, 40000]
has
_.has(object, key)
对象是否包含给定的键吗?等同于object.hasOwnProperty(key),但是使用hasOwnProperty 函数的一个安全引用,以防意外覆盖。
_.has({a: 1, b: 2, c: 3}, "b") => true
property
_.property(path)
返回一个函数,该函数将返回任何传入对象的指定属性。 path 可以指定为简单 key(键),或者指定为对象键或数组索引的数组,用于深度属性提取。
var stooge = {name: 'moe'}; 'moe' === _.property('name')(stooge); => true var stooges = {moe: {fears: {worst: 'Spiders'}}, curly: {fears: {worst: 'Moe'}}}; var curlysWorstFear = _.property(['curly', 'fears', 'worst']); curlysWorstFear(stooges); => 'Moe'
propertyOf
_.propertyOf(object)
_.property 的反操作。 获取一个对象并返回一个函数,该函数将返回提供的属性的值。
var stooge = {name: 'moe'}; _.propertyOf(stooge)('name'); => 'moe'
matcher
_.matcher(attrs) Alias: matches
返回一个断言函数,这个函数会给你一个断言可以用来辨别给定的对象是否匹配attrs指定键/值属性。
var ready = _.matcher({selected: true, visible: true}); var readyToGoList = _.filter(list, ready);
isEqual
_.isEqual(object, other)
执行两个对象之间的优化深度比较,确定他们是否应被视为相等。
var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]}; var clone = {name: 'moe', luckyNumbers: [13, 27, 34]}; stooge == clone; => false _.isEqual(stooge, clone); => true
isMatch
_.isMatch(object, properties)
告诉你properties中的键和值是否包含在object中。
var stooge = {name: 'moe', age: 32}; _.isMatch(stooge, {age: 32}); => true
isEmpty
_.isEmpty(object)
如果object 不包含任何值(没有可枚举的属性),返回true。 对于字符串和类数组(array-like)对象,如果length属性为 0,那么_.isEmpty检查返回true。
_.isEmpty([1, 2, 3]); => false _.isEmpty({}); => true
isElement
_.isElement(object)
如果object是一个DOM元素,返回true。
_.isElement(jQuery('body')[0]); => true
isArray
_.isArray(object)
如果object是一个数组,返回true。
(function(){ return _.isArray(arguments); })(); => false _.isArray([1,2,3]); => true
isObject
_.isObject(value)
如果object是一个对象,返回true。需要注意的是JavaScript数组和函数是对象,字符串和数字不是。
_.isObject({}); => true _.isObject(1); => false
isArguments
_.isArguments(object)
如果object是一个参数对象,返回true。
(function(){ return _.isArguments(arguments); })(1, 2, 3); => true _.isArguments([1,2,3]); => false
isFunction
_.isFunction(object)
如果object是一个函数(Function),返回true。
_.isFunction(alert); => true
isString
_.isString(object)
如果object是一个字符串,返回true。
_.isString("moe"); => true
isNumber
_.isNumber(object)
如果object是一个数值,返回true (包括 NaN)。
_.isNumber(8.4 * 5); => true
isFinite
_.isFinite(object)
如果object是一个有限的数字,返回true。
_.isFinite(-101); => true _.isFinite(-Infinity); => false
isBoolean
_.isBoolean(object)
如果object是一个布尔值,返回true,否则返回false。
_.isBoolean(null); => false
isDate
_.isDate(object)
如果object是一个 Date(日期),返回true。
_.isDate(new Date()); => true
isRegExp
_.isRegExp(object)
如果object是一个正则表达式,返回true。
_.isRegExp(/moe/); => true
isError
_.isError(object)
如果object继承至 Error 对象,那么返回 true。
try { throw new TypeError("Example"); } catch (o_O) { _.isError(o_O); } => true
isSymbol
_.isSymbol(object)
如果object是一个 Symbol ,那么返回 true。
_.isSymbol(Symbol()); => true
isMap
_.isMap(object)
如果object是一个 Map ,那么返回 true。
_.isMap(new Map()); => true
isWeakMap
_.isWeakMap(object)
如果object是一个 WeakMap,那么返回 true。
_.isWeakMap(new WeakMap()); => true
isSet
_.isSet(object)
如果object是一个 Set,那么返回 true。
_.isSet(new Set()); => true
isWeakSet
_.isWeakSet(object)
如果object是一个 WeakSet,那么返回 true。
_.isWeakSet(WeakSet()); => true
isNaN
_.isNaN(object)
如果object是 NaN,返回true。
注意: 这和原生的isNaN 函数不一样,如果变量是undefined,原生的isNaN 函数也会返回 true 。
_.isNaN(NaN); => true isNaN(undefined); => true _.isNaN(undefined); => false
isNull
_.isNull(object)
如果object的值是 null,返回true。
_.isNull(null); => true _.isNull(undefined); => false
isUndefined
_.isUndefined(value)
如果value是undefined,返回true。
_.isUndefined(window.missingVariable); => true