underscore.js So what exactly does Underscore do? "Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects. One of the nicer things about working in Python or Ruby are the fancy constructs like map that make life a lot easier. The current version of JavaScript, sadly, is fairly barebones when it comes to low level utilities." Object Functions allKeys _.allKeys(object) Retrieve all the property names of an object. _.allKeys = function(obj) { if (!_.isObject(obj)) return []; var keys = []; for (var key in obj) keys.push(key); if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; }; Retrieve all the names of object's own and inherited properties. function Stooge(name) { this.name = name; } Stooge.prototype.silly = true; _.allKeys(new Stooge("Moe")); >> ["name", "silly"] keys _.keys(object) Retrieve the names of an object’s own properties. Delegates to ECMAScript 5‘s native Object.keys _.keys = function(obj) { if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; }; Retrieve all the names of the object's own enumerable properties. _.keys({one: 1, two: 2, three: 3}); >> ["one", "two", "three"] create _.create(prototype, props) Creates an object that inherits from the given prototype object. If additional properties are provided then they will be added to the created object. _.create = function(prototype, props) { var result = baseCreate(prototype); if (props) _.extendOwn(result, props); return result; }; Creates a new object with the given prototype, optionally attaching props as own properties. Basically, Object.create, but without all of the property descriptor jazz. var moe = _.create(Stooge.prototype, {name: "Moe"}); values _.values(object) Retrieve the values of an object’s properties. _.values = function(obj) { var keys = _.keys(obj); var length = keys.length; var values = Array(length); for (var i = 0; i < length; i++) { values[i] = obj[keys[i]]; } return values; }; Return all of the values of the object's own properties. _.values({one: 1, two: 2, three: 3}); >> [1, 2, 3] pairs _.pairs(object) Convert an object into a list of [key, value] pairs. _.pairs = function(obj) { var keys = _.keys(obj); var length = keys.length; var pairs = Array(length); for (var i = 0; i < length; i++) { pairs[i] = [keys[i], obj[keys[i]]]; } return pairs; }; Convert an object into a list of [key, value] pairs. _.pairs({one: 1, two: 2, three: 3}); >> [["one", 1], ["two", 2], ["three", 3]] invert _.invert(object) Invert the keys and values of an object. The values must be serializable. _.invert = function(obj) { var result = {}; var keys = _.keys(obj); for (var i = 0, length = keys.length; i < length; i++) { result[obj[keys[i]]] = keys[i]; } return result; }; Returns a copy of the object where the keys have become the values and the values the keys. For this to work, all of your object's values should be unique and string serializable. _.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"}); >> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"}; extend _.extend(destination, *sources) Extend a given object with all the properties in passed-in object(s). _.extend = createAssigner(_.allKeys); Shallowly copy all of the properties in the source objects over to the destination object, and return the destination object. Any nested objects or arrays will be copied by reference, not duplicated. It's in-order, so the last source will override properties of the same name in previous arguments. _.extend({name: 'moe'}, {age: 50}); >> {name: 'moe', age: 50} pick _.pick(object, *keys) Return a copy of the object only containing the whitelisted properties. _.pick = function(object, oiteratee, context) { var result = {}, obj = object, iteratee, keys; if (obj == null) return result; if (_.isFunction(oiteratee)) { keys = _.allKeys(obj); iteratee = optimizeCb(oiteratee, context); } else { keys = flatten(arguments, false, false, 1); iteratee = function(value, key, obj) { return key in obj; }; obj = Object(obj); } for (var i = 0, length = keys.length; i < length; i++) { var key = keys[i]; var value = obj[key]; if (iteratee(value, key, obj)) result[key] = value; } return result; }; Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys). Alternatively accepts a predicate indicating which keys to pick. _.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) Return a copy of the object without the blacklisted properties. _.omit = function(obj, iteratee, context) { if (_.isFunction(iteratee)) { iteratee = _.negate(iteratee); } else { var keys = _.map(flatten(arguments, false, false, 1), String); iteratee = function(value, key) { return !_.contains(keys, key); }; } return _.pick(obj, iteratee, context); }; Return a copy of the object, filtered to omit the blacklisted keys (or array of keys). Alternatively accepts a predicate indicating which keys to omit. _.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'} has _.has(object, key) Shortcut function for checking if an object has a given property directly on itself (in other words, not on a prototype). _.has = function(obj, key) { return obj != null && hasOwnProperty.call(obj, key); }; Does the object contain the given key? Identical to object.hasOwnProperty(key), but uses a safe reference to the hasOwnProperty function, in case it's been overridden accidentally. _.has({a: 1, b: 2, c: 3}, "b"); >> true tap _.tap(object, interceptor) Invokes interceptor with the obj, and then returns obj. The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain. _.tap = function(obj, interceptor) { interceptor(obj); return obj; }; Invokes interceptor with the object, and then returns object. The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. _.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] isMatch _.isMatch(object, properties) Returns whether an object has a given set of key:value pairs. _.isMatch = function(object, attrs) { var keys = _.keys(attrs), length = keys.length; if (object == null) return !length; var obj = Object(object); for (var i = 0; i < length; i++) { var key = keys[i]; if (attrs[key] !== obj[key] || !(key in obj)) return false; } return true; }; Tells you if the keys and values in properties are contained in object. var stooge = {name: 'moe', age: 32}; _.isMatch(stooge, {age: 32}); >> true isEqual _.isEqual(object, other) Internal recursive comparison function for isEqual. _.isEqual = function(a, b) { return eq(a, b); }; Performs an optimized deep comparison between the two objects, to determine if they should be considered equal. var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]}; var clone = {name: 'moe', luckyNumbers: [13, 27, 34]}; stooge == clone; >> false _.isEqual(stooge, clone); >> true isEmpty _.isEmpty(object) Is a given array, string, or object empty? An “empty” object has no enumerable own-properties. _.isEmpty = function(obj) { if (obj == null) return true; if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; return _.keys(obj).length === 0; }; Returns true if an enumerable object contains no values (no enumerable own-properties). For strings and array-like objects _.isEmpty checks if the length property is 0. _.isEmpty([1, 2, 3]); >> false _.isEmpty({}); >> true isArray _.isArray(object) Is a given value an array? Delegates to ECMA5’s native Array.isArray _.isArray = nativeIsArray || function(obj) { return toString.call(obj) === '[object Array]'; }; Returns true if object is an Array. (function(){ return _.isArray(arguments); })(); >> false _.isArray([1,2,3]); >> true isObject _.isObject(value) Is a given variable an object? _.isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; }; Returns true if value is an Object. Note that JavaScript arrays and functions are objects, while (normal) strings and numbers are not. _.isObject({}); >> true _.isObject(1); >> false isArguments _.isArguments(object) Define a fallback version of the method in browsers (ahem, IE < 9), where there isn’t any inspectable “Arguments” type. if (!_.isArguments(arguments)) { _.isArguments = function(obj) { return _.has(obj, 'callee'); }; } Returns true if object is an Arguments object. (function(){ return _.isArguments(arguments); })(1, 2, 3); >> true _.isArguments([1,2,3]); >> false isNull _.isNull(object) Is a given value equal to null? _.isNaN = function(obj) { return _.isNumber(obj) && obj !== +obj; }; Returns true if the value of object is null. _.isNull(null); >> true _.isNull(undefined); >> false isUndefined _.isUndefined(value) Is a given variable undefined? _.isUndefined = function(obj) { return obj === void 0; }; Returns true if value is undefined. _.isUndefined(window.missingVariable); >> true