diff --git a/underscore/.gitignore b/underscore/.gitignore deleted file mode 100644 index 48ecc30..0000000 --- a/underscore/.gitignore +++ /dev/null @@ -1 +0,0 @@ -raw \ No newline at end of file diff --git a/underscore/.npmignore b/underscore/.npmignore deleted file mode 100644 index 2ce2684..0000000 --- a/underscore/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -test/ -Rakefile -docs/ \ No newline at end of file diff --git a/underscore/CNAME b/underscore/CNAME deleted file mode 100644 index a007e65..0000000 --- a/underscore/CNAME +++ /dev/null @@ -1 +0,0 @@ -underscorejs.org diff --git a/underscore/CONTRIBUTING.md b/underscore/CONTRIBUTING.md deleted file mode 100644 index 36a9934..0000000 --- a/underscore/CONTRIBUTING.md +++ /dev/null @@ -1,9 +0,0 @@ -## How to contribute to Underscore.js - -* Before you open a ticket or send a pull request, [search](https://github.com/documentcloud/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one. - -* Before sending a pull request for a feature, be sure to have [tests](http://underscorejs.org/test/test.html). - -* Use the same coding style as the rest of the [codebase](https://github.com/documentcloud/underscore/blob/master/underscore.js). - -* In your pull request, do not add documentation or re-build the minified `underscore-min.js` file. We'll do those things before cutting a new release. \ No newline at end of file diff --git a/underscore/LICENSE b/underscore/LICENSE deleted file mode 100644 index 61d28c0..0000000 --- a/underscore/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/underscore/README.md b/underscore/README.md deleted file mode 100644 index b1f3e50..0000000 --- a/underscore/README.md +++ /dev/null @@ -1,19 +0,0 @@ - __ - /\ \ __ - __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ - /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ - \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ - \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ - \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ - \ \____/ - \/___/ - -Underscore.js is a utility-belt library for JavaScript that provides -support for the usual functional suspects (each, map, reduce, filter...) -without extending any core JavaScript objects. - -For Docs, License, Tests, and pre-packed downloads, see: -http://underscorejs.org - -Many thanks to our contributors: -https://github.com/documentcloud/underscore/contributors diff --git a/underscore/Rakefile b/underscore/Rakefile deleted file mode 100644 index b9fd1ca..0000000 --- a/underscore/Rakefile +++ /dev/null @@ -1,15 +0,0 @@ -require 'rubygems' -require 'uglifier' - -desc "Use the Closure Compiler to compress Underscore.js" -task :build do - source = File.read('underscore.js') - min = Uglifier.compile(source) - File.open('underscore-min.js', 'w') {|f| f.write min } -end - -desc "Build the docco documentation" -task :doc do - sh "docco underscore.js" -end - diff --git a/underscore/docs/docco.css b/underscore/docs/docco.css deleted file mode 100644 index 04cc7ec..0000000 --- a/underscore/docs/docco.css +++ /dev/null @@ -1,192 +0,0 @@ -/*--------------------- Layout and Typography ----------------------------*/ -body { - font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; - font-size: 15px; - line-height: 22px; - color: #252519; - margin: 0; padding: 0; -} -a { - color: #261a3b; -} - a:visited { - color: #261a3b; - } -p { - margin: 0 0 15px 0; -} -h1, h2, h3, h4, h5, h6 { - margin: 0px 0 15px 0; -} - h1 { - margin-top: 40px; - } -hr { - border: 0 none; - border-top: 1px solid #e5e5ee; - height: 1px; - margin: 20px 0; -} -#container { - position: relative; -} -#background { - position: fixed; - top: 0; left: 525px; right: 0; bottom: 0; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - z-index: -1; -} -#jump_to, #jump_page { - background: white; - -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; - -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; - font: 10px Arial; - text-transform: uppercase; - cursor: pointer; - text-align: right; -} -#jump_to, #jump_wrapper { - position: fixed; - right: 0; top: 0; - padding: 5px 10px; -} - #jump_wrapper { - padding: 0; - display: none; - } - #jump_to:hover #jump_wrapper { - display: block; - } - #jump_page { - padding: 5px 0 3px; - margin: 0 0 25px 25px; - } - #jump_page .source { - display: block; - padding: 5px 10px; - text-decoration: none; - border-top: 1px solid #eee; - } - #jump_page .source:hover { - background: #f5f5ff; - } - #jump_page .source:first-child { - } -table td { - border: 0; - outline: 0; -} - td.docs, th.docs { - max-width: 450px; - min-width: 450px; - min-height: 5px; - padding: 10px 25px 1px 50px; - overflow-x: hidden; - vertical-align: top; - text-align: left; - } - .docs pre { - margin: 15px 0 15px; - padding-left: 15px; - } - .docs p tt, .docs p code { - background: #f8f8ff; - border: 1px solid #dedede; - font-size: 12px; - padding: 0 0.2em; - } - .pilwrap { - position: relative; - } - .pilcrow { - font: 12px Arial; - text-decoration: none; - color: #454545; - position: absolute; - top: 3px; left: -20px; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; - } - td.docs:hover .pilcrow { - opacity: 1; - } - td.code, th.code { - padding: 14px 15px 16px 25px; - width: 100%; - vertical-align: top; - background: #f5f5ff; - border-left: 1px solid #e5e5ee; - } - pre, tt, code { - font-size: 12px; line-height: 18px; - font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; - margin: 0; padding: 0; - } - - -/*---------------------- Syntax Highlighting -----------------------------*/ -td.linenos { background-color: #f0f0f0; padding-right: 10px; } -span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } -body .hll { background-color: #ffffcc } -body .c { color: #408080; font-style: italic } /* Comment */ -body .err { border: 1px solid #FF0000 } /* Error */ -body .k { color: #954121 } /* Keyword */ -body .o { color: #666666 } /* Operator */ -body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -body .cp { color: #BC7A00 } /* Comment.Preproc */ -body .c1 { color: #408080; font-style: italic } /* Comment.Single */ -body .cs { color: #408080; font-style: italic } /* Comment.Special */ -body .gd { color: #A00000 } /* Generic.Deleted */ -body .ge { font-style: italic } /* Generic.Emph */ -body .gr { color: #FF0000 } /* Generic.Error */ -body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -body .gi { color: #00A000 } /* Generic.Inserted */ -body .go { color: #808080 } /* Generic.Output */ -body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -body .gs { font-weight: bold } /* Generic.Strong */ -body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -body .gt { color: #0040D0 } /* Generic.Traceback */ -body .kc { color: #954121 } /* Keyword.Constant */ -body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ -body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ -body .kp { color: #954121 } /* Keyword.Pseudo */ -body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ -body .kt { color: #B00040 } /* Keyword.Type */ -body .m { color: #666666 } /* Literal.Number */ -body .s { color: #219161 } /* Literal.String */ -body .na { color: #7D9029 } /* Name.Attribute */ -body .nb { color: #954121 } /* Name.Builtin */ -body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -body .no { color: #880000 } /* Name.Constant */ -body .nd { color: #AA22FF } /* Name.Decorator */ -body .ni { color: #999999; font-weight: bold } /* Name.Entity */ -body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -body .nf { color: #0000FF } /* Name.Function */ -body .nl { color: #A0A000 } /* Name.Label */ -body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -body .nt { color: #954121; font-weight: bold } /* Name.Tag */ -body .nv { color: #19469D } /* Name.Variable */ -body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -body .w { color: #bbbbbb } /* Text.Whitespace */ -body .mf { color: #666666 } /* Literal.Number.Float */ -body .mh { color: #666666 } /* Literal.Number.Hex */ -body .mi { color: #666666 } /* Literal.Number.Integer */ -body .mo { color: #666666 } /* Literal.Number.Oct */ -body .sb { color: #219161 } /* Literal.String.Backtick */ -body .sc { color: #219161 } /* Literal.String.Char */ -body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ -body .s2 { color: #219161 } /* Literal.String.Double */ -body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -body .sh { color: #219161 } /* Literal.String.Heredoc */ -body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -body .sx { color: #954121 } /* Literal.String.Other */ -body .sr { color: #BB6688 } /* Literal.String.Regex */ -body .s1 { color: #219161 } /* Literal.String.Single */ -body .ss { color: #19469D } /* Literal.String.Symbol */ -body .bp { color: #954121 } /* Name.Builtin.Pseudo */ -body .vc { color: #19469D } /* Name.Variable.Class */ -body .vg { color: #19469D } /* Name.Variable.Global */ -body .vi { color: #19469D } /* Name.Variable.Instance */ -body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/underscore/docs/favicon.ico b/underscore/docs/favicon.ico deleted file mode 100644 index 0304968..0000000 Binary files a/underscore/docs/favicon.ico and /dev/null differ diff --git a/underscore/docs/images/background.png b/underscore/docs/images/background.png deleted file mode 100644 index 90ee693..0000000 Binary files a/underscore/docs/images/background.png and /dev/null differ diff --git a/underscore/docs/images/underscore.png b/underscore/docs/images/underscore.png deleted file mode 100644 index dce9edb..0000000 Binary files a/underscore/docs/images/underscore.png and /dev/null differ diff --git a/underscore/docs/underscore.html b/underscore/docs/underscore.html deleted file mode 100644 index 1f4b86a..0000000 --- a/underscore/docs/underscore.html +++ /dev/null @@ -1,800 +0,0 @@ -
underscore.js | |
---|---|
| (function() { |
Baseline setup | |
Establish the root object, | var root = this; |
Save the previous value of the | var previousUnderscore = root._; |
Establish the object that gets returned to break out of a loop iteration. | var breaker = {}; |
Save bytes in the minified (but not gzipped) version: | var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; |
Create quick reference variables for speed access to core prototypes. | var push = ArrayProto.push,
- slice = ArrayProto.slice,
- concat = ArrayProto.concat,
- unshift = ArrayProto.unshift,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty; |
All ECMAScript 5 native function implementations that we hope to use -are declared here. | var
- nativeForEach = ArrayProto.forEach,
- nativeMap = ArrayProto.map,
- nativeReduce = ArrayProto.reduce,
- nativeReduceRight = ArrayProto.reduceRight,
- nativeFilter = ArrayProto.filter,
- nativeEvery = ArrayProto.every,
- nativeSome = ArrayProto.some,
- nativeIndexOf = ArrayProto.indexOf,
- nativeLastIndexOf = ArrayProto.lastIndexOf,
- nativeIsArray = Array.isArray,
- nativeKeys = Object.keys,
- nativeBind = FuncProto.bind; |
Create a safe reference to the Underscore object for use below. | var _ = function(obj) {
- if (obj instanceof _) return obj;
- if (!(this instanceof _)) return new _(obj);
- this._wrapped = obj;
- }; |
Export the Underscore object for Node.js, with
-backwards-compatibility for the old | if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
- exports = module.exports = _;
- }
- exports._ = _;
- } else {
- root['_'] = _;
- } |
Current version. | _.VERSION = '1.4.2'; |
Collection Functions | |
The cornerstone, an | var each = _.each = _.forEach = function(obj, iterator, context) {
- if (obj == null) return;
- if (nativeForEach && obj.forEach === nativeForEach) {
- obj.forEach(iterator, context);
- } else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
- if (iterator.call(context, obj[i], i, obj) === breaker) return;
- }
- } else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
- }
- }
- }; |
Return the results of applying the iterator to each element.
-Delegates to ECMAScript 5's native | _.map = _.collect = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
- each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
- });
- return results;
- }; |
Reduce builds up a single result from a list of values, aka | _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduce && obj.reduce === nativeReduce) {
- if (context) iterator = _.bind(iterator, context);
- return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
- }
- each(obj, function(value, index, list) {
- if (!initial) {
- memo = value;
- initial = true;
- } else {
- memo = iterator.call(context, memo, value, index, list);
- }
- });
- if (!initial) throw new TypeError('Reduce of empty array with no initial value');
- return memo;
- }; |
The right-associative version of reduce, also known as | _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
- var initial = arguments.length > 2;
- if (obj == null) obj = [];
- if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
- if (context) iterator = _.bind(iterator, context);
- return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
- }
- var length = obj.length;
- if (length !== +length) {
- var keys = _.keys(obj);
- length = keys.length;
- }
- each(obj, function(value, index, list) {
- index = keys ? keys[--length] : --length;
- if (!initial) {
- memo = obj[index];
- initial = true;
- } else {
- memo = iterator.call(context, memo, obj[index], index, list);
- }
- });
- if (!initial) throw new TypeError('Reduce of empty array with no initial value');
- return memo;
- }; |
Return the first value which passes a truth test. Aliased as | _.find = _.detect = function(obj, iterator, context) {
- var result;
- any(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) {
- result = value;
- return true;
- }
- });
- return result;
- }; |
Return all the elements that pass a truth test.
-Delegates to ECMAScript 5's native | _.filter = _.select = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
- each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
- }; |
Return all the elements for which a truth test fails. | _.reject = function(obj, iterator, context) {
- var results = [];
- if (obj == null) return results;
- each(obj, function(value, index, list) {
- if (!iterator.call(context, value, index, list)) results[results.length] = value;
- });
- return results;
- }; |
Determine whether all of the elements match a truth test.
-Delegates to ECMAScript 5's native | _.every = _.all = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
- var result = true;
- if (obj == null) return result;
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
- each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
- });
- return !!result;
- }; |
Determine if at least one element in the object matches a truth test.
-Delegates to ECMAScript 5's native | var any = _.some = _.any = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
- var result = false;
- if (obj == null) return result;
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
- each(obj, function(value, index, list) {
- if (result || (result = iterator.call(context, value, index, list))) return breaker;
- });
- return !!result;
- }; |
Determine if the array or object contains a given value (using | _.contains = _.include = function(obj, target) {
- var found = false;
- if (obj == null) return found;
- if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
- found = any(obj, function(value) {
- return value === target;
- });
- return found;
- }; |
Invoke a method (with arguments) on every item in a collection. | _.invoke = function(obj, method) {
- var args = slice.call(arguments, 2);
- return _.map(obj, function(value) {
- return (_.isFunction(method) ? method : value[method]).apply(value, args);
- });
- }; |
Convenience version of a common use case of | _.pluck = function(obj, key) {
- return _.map(obj, function(value){ return value[key]; });
- }; |
Convenience version of a common use case of | _.where = function(obj, attrs) {
- if (_.isEmpty(attrs)) return [];
- return _.filter(obj, function(value) {
- for (var key in attrs) {
- if (attrs[key] !== value[key]) return false;
- }
- return true;
- });
- }; |
Return the maximum element or (element-based computation). -Can't optimize arrays of integers longer than 65,535 elements. -See: https://bugs.webkit.org/show_bug.cgi?id=80797 | _.max = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
- return Math.max.apply(Math, obj);
- }
- if (!iterator && _.isEmpty(obj)) return -Infinity;
- var result = {computed : -Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed >= result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- }; |
Return the minimum element (or element-based computation). | _.min = function(obj, iterator, context) {
- if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
- return Math.min.apply(Math, obj);
- }
- if (!iterator && _.isEmpty(obj)) return Infinity;
- var result = {computed : Infinity};
- each(obj, function(value, index, list) {
- var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed < result.computed && (result = {value : value, computed : computed});
- });
- return result.value;
- }; |
Shuffle an array. | _.shuffle = function(obj) {
- var rand;
- var index = 0;
- var shuffled = [];
- each(obj, function(value) {
- rand = _.random(index++);
- shuffled[index - 1] = shuffled[rand];
- shuffled[rand] = value;
- });
- return shuffled;
- }; |
An internal function to generate lookup iterators. | var lookupIterator = function(value) {
- return _.isFunction(value) ? value : function(obj){ return obj[value]; };
- }; |
Sort the object's values by a criterion produced by an iterator. | _.sortBy = function(obj, value, context) {
- var iterator = lookupIterator(value);
- return _.pluck(_.map(obj, function(value, index, list) {
- return {
- value : value,
- index : index,
- criteria : iterator.call(context, value, index, list)
- };
- }).sort(function(left, right) {
- var a = left.criteria;
- var b = right.criteria;
- if (a !== b) {
- if (a > b || a === void 0) return 1;
- if (a < b || b === void 0) return -1;
- }
- return left.index < right.index ? -1 : 1;
- }), 'value');
- }; |
An internal function used for aggregate "group by" operations. | var group = function(obj, value, context, behavior) {
- var result = {};
- var iterator = lookupIterator(value);
- each(obj, function(value, index) {
- var key = iterator.call(context, value, index, obj);
- behavior(result, key, value);
- });
- return result;
- }; |
Groups the object's values by a criterion. Pass either a string attribute -to group by, or a function that returns the criterion. | _.groupBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
- });
- }; |
Counts instances of an object that group by a certain criterion. Pass -either a string attribute to count by, or a function that returns the -criterion. | _.countBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- if (!_.has(result, key)) result[key] = 0;
- result[key]++;
- });
- }; |
Use a comparator function to figure out the smallest index at which -an object should be inserted so as to maintain order. Uses binary search. | _.sortedIndex = function(array, obj, iterator, context) {
- iterator = iterator == null ? _.identity : lookupIterator(iterator);
- var value = iterator.call(context, obj);
- var low = 0, high = array.length;
- while (low < high) {
- var mid = (low + high) >>> 1;
- iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
- }
- return low;
- }; |
Safely convert anything iterable into a real, live array. | _.toArray = function(obj) {
- if (!obj) return [];
- if (obj.length === +obj.length) return slice.call(obj);
- return _.values(obj);
- }; |
Return the number of elements in an object. | _.size = function(obj) {
- return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
- }; |
Array Functions | |
Get the first element of an array. Passing n will return the first N
-values in the array. Aliased as | _.first = _.head = _.take = function(array, n, guard) {
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
- }; |
Returns everything but the last entry of the array. Especially useful on
-the arguments object. Passing n will return all the values in
-the array, excluding the last N. The guard check allows it to work with
- | _.initial = function(array, n, guard) {
- return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
- }; |
Get the last element of an array. Passing n will return the last N
-values in the array. The guard check allows it to work with | _.last = function(array, n, guard) {
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
- return array[array.length - 1];
- }
- }; |
Returns everything but the first entry of the array. Aliased as | _.rest = _.tail = _.drop = function(array, n, guard) {
- return slice.call(array, (n == null) || guard ? 1 : n);
- }; |
Trim out all falsy values from an array. | _.compact = function(array) {
- return _.filter(array, function(value){ return !!value; });
- }; |
Internal implementation of a recursive | var flatten = function(input, shallow, output) {
- each(input, function(value) {
- if (_.isArray(value)) {
- shallow ? push.apply(output, value) : flatten(value, shallow, output);
- } else {
- output.push(value);
- }
- });
- return output;
- }; |
Return a completely flattened version of an array. | _.flatten = function(array, shallow) {
- return flatten(array, shallow, []);
- }; |
Return a version of the array that does not contain the specified value(s). | _.without = function(array) {
- return _.difference(array, slice.call(arguments, 1));
- }; |
Produce a duplicate-free version of the array. If the array has already
-been sorted, you have the option of using a faster algorithm.
-Aliased as | _.uniq = _.unique = function(array, isSorted, iterator, context) {
- var initial = iterator ? _.map(array, iterator, context) : array;
- var results = [];
- var seen = [];
- each(initial, function(value, index) {
- if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
- seen.push(value);
- results.push(array[index]);
- }
- });
- return results;
- }; |
Produce an array that contains the union: each distinct element from all of -the passed-in arrays. | _.union = function() {
- return _.uniq(concat.apply(ArrayProto, arguments));
- }; |
Produce an array that contains every item shared between all the -passed-in arrays. | _.intersection = function(array) {
- var rest = slice.call(arguments, 1);
- return _.filter(_.uniq(array), function(item) {
- return _.every(rest, function(other) {
- return _.indexOf(other, item) >= 0;
- });
- });
- }; |
Take the difference between one array and a number of other arrays. -Only the elements present in just the first array will remain. | _.difference = function(array) {
- var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
- return _.filter(array, function(value){ return !_.contains(rest, value); });
- }; |
Zip together multiple lists into a single array -- elements that share -an index go together. | _.zip = function() {
- var args = slice.call(arguments);
- var length = _.max(_.pluck(args, 'length'));
- var results = new Array(length);
- for (var i = 0; i < length; i++) {
- results[i] = _.pluck(args, "" + i);
- }
- return results;
- }; |
Converts lists into objects. Pass either a single array of | _.object = function(list, values) {
- var result = {};
- for (var i = 0, l = list.length; i < l; i++) {
- if (values) {
- result[list[i]] = values[i];
- } else {
- result[list[i][0]] = list[i][1];
- }
- }
- return result;
- }; |
If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
-we need this function. Return the position of the first occurrence of an
-item in an array, or -1 if the item is not included in the array.
-Delegates to ECMAScript 5's native | _.indexOf = function(array, item, isSorted) {
- if (array == null) return -1;
- var i = 0, l = array.length;
- if (isSorted) {
- if (typeof isSorted == 'number') {
- i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
- } else {
- i = _.sortedIndex(array, item);
- return array[i] === item ? i : -1;
- }
- }
- if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
- for (; i < l; i++) if (array[i] === item) return i;
- return -1;
- }; |
Delegates to ECMAScript 5's native | _.lastIndexOf = function(array, item, from) {
- if (array == null) return -1;
- var hasIndex = from != null;
- if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
- return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
- }
- var i = (hasIndex ? from : array.length);
- while (i--) if (array[i] === item) return i;
- return -1;
- }; |
Generate an integer Array containing an arithmetic progression. A port of
-the native Python | _.range = function(start, stop, step) {
- if (arguments.length <= 1) {
- stop = start || 0;
- start = 0;
- }
- step = arguments[2] || 1;
-
- var len = Math.max(Math.ceil((stop - start) / step), 0);
- var idx = 0;
- var range = new Array(len);
-
- while(idx < len) {
- range[idx++] = start;
- start += step;
- }
-
- return range;
- }; |
Function (ahem) Functions | |
Reusable constructor function for prototype setting. | var ctor = function(){}; |
Create a function bound to a given object (assigning | _.bind = function bind(func, context) {
- var bound, args;
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
- if (!_.isFunction(func)) throw new TypeError;
- args = slice.call(arguments, 2);
- return bound = function() {
- if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
- ctor.prototype = func.prototype;
- var self = new ctor;
- var result = func.apply(self, args.concat(slice.call(arguments)));
- if (Object(result) === result) return result;
- return self;
- };
- }; |
Bind all of an object's methods to that object. Useful for ensuring that -all callbacks defined on an object belong to it. | _.bindAll = function(obj) {
- var funcs = slice.call(arguments, 1);
- if (funcs.length == 0) funcs = _.functions(obj);
- each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
- return obj;
- }; |
Memoize an expensive function by storing its results. | _.memoize = function(func, hasher) {
- var memo = {};
- hasher || (hasher = _.identity);
- return function() {
- var key = hasher.apply(this, arguments);
- return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
- };
- }; |
Delays a function for the given number of milliseconds, and then calls -it with the arguments supplied. | _.delay = function(func, wait) {
- var args = slice.call(arguments, 2);
- return setTimeout(function(){ return func.apply(null, args); }, wait);
- }; |
Defers a function, scheduling it to run after the current call stack has -cleared. | _.defer = function(func) {
- return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
- }; |
Returns a function, that, when invoked, will only be triggered at most once -during a given window of time. | _.throttle = function(func, wait) {
- var context, args, timeout, throttling, more, result;
- var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
- return function() {
- context = this; args = arguments;
- var later = function() {
- timeout = null;
- if (more) {
- result = func.apply(context, args);
- }
- whenDone();
- };
- if (!timeout) timeout = setTimeout(later, wait);
- if (throttling) {
- more = true;
- } else {
- throttling = true;
- result = func.apply(context, args);
- }
- whenDone();
- return result;
- };
- }; |
Returns a function, that, as long as it continues to be invoked, will not
-be triggered. The function will be called after it stops being called for
-N milliseconds. If | _.debounce = function(func, wait, immediate) {
- var timeout, result;
- return function() {
- var context = this, args = arguments;
- var later = function() {
- timeout = null;
- if (!immediate) result = func.apply(context, args);
- };
- var callNow = immediate && !timeout;
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- if (callNow) result = func.apply(context, args);
- return result;
- };
- }; |
Returns a function that will be executed at most one time, no matter how -often you call it. Useful for lazy initialization. | _.once = function(func) {
- var ran = false, memo;
- return function() {
- if (ran) return memo;
- ran = true;
- memo = func.apply(this, arguments);
- func = null;
- return memo;
- };
- }; |
Returns the first function passed as an argument to the second, -allowing you to adjust arguments, run code before and after, and -conditionally execute the original function. | _.wrap = function(func, wrapper) {
- return function() {
- var args = [func];
- push.apply(args, arguments);
- return wrapper.apply(this, args);
- };
- }; |
Returns a function that is the composition of a list of functions, each -consuming the return value of the function that follows. | _.compose = function() {
- var funcs = arguments;
- return function() {
- var args = arguments;
- for (var i = funcs.length - 1; i >= 0; i--) {
- args = [funcs[i].apply(this, args)];
- }
- return args[0];
- };
- }; |
Returns a function that will only be executed after being called N times. | _.after = function(times, func) {
- if (times <= 0) return func();
- return function() {
- if (--times < 1) {
- return func.apply(this, arguments);
- }
- };
- }; |
Object Functions | |
Retrieve the names of an object's properties.
-Delegates to ECMAScript 5's native | _.keys = nativeKeys || function(obj) {
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
- var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
- return keys;
- }; |
Retrieve the values of an object's properties. | _.values = function(obj) {
- var values = [];
- for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
- return values;
- }; |
Convert an object into a list of | _.pairs = function(obj) {
- var pairs = [];
- for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
- return pairs;
- }; |
Invert the keys and values of an object. The values must be serializable. | _.invert = function(obj) {
- var result = {};
- for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
- return result;
- }; |
Return a sorted list of the function names available on the object.
-Aliased as | _.functions = _.methods = function(obj) {
- var names = [];
- for (var key in obj) {
- if (_.isFunction(obj[key])) names.push(key);
- }
- return names.sort();
- }; |
Extend a given object with all the properties in passed-in object(s). | _.extend = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- obj[prop] = source[prop];
- }
- });
- return obj;
- }; |
Return a copy of the object only containing the whitelisted properties. | _.pick = function(obj) {
- var copy = {};
- var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
- each(keys, function(key) {
- if (key in obj) copy[key] = obj[key];
- });
- return copy;
- }; |
Return a copy of the object without the blacklisted properties. | _.omit = function(obj) {
- var copy = {};
- var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
- for (var key in obj) {
- if (!_.contains(keys, key)) copy[key] = obj[key];
- }
- return copy;
- }; |
Fill in a given object with default properties. | _.defaults = function(obj) {
- each(slice.call(arguments, 1), function(source) {
- for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
- }
- });
- return obj;
- }; |
Create a (shallow-cloned) duplicate of an object. | _.clone = function(obj) {
- if (!_.isObject(obj)) return obj;
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
- }; |
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;
- }; |
Internal recursive comparison function for | var eq = function(a, b, aStack, bStack) { |
Identical objects are equal. | if (a === b) return a !== 0 || 1 / a == 1 / b; |
A strict comparison is necessary because | if (a == null || b == null) return a === b; |
Unwrap any wrapped objects. | if (a instanceof _) a = a._wrapped;
- if (b instanceof _) b = b._wrapped; |
Compare | var className = toString.call(a);
- if (className != toString.call(b)) return false;
- switch (className) { |
Strings, numbers, dates, and booleans are compared by value. | case '[object String]': |
Primitives and their corresponding object wrappers are equivalent; thus, | return a == String(b);
- case '[object Number]': |
| return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
- case '[object Date]':
- case '[object Boolean]': |
Coerce dates and booleans to numeric primitive values. Dates are compared by their
-millisecond representations. Note that invalid dates with millisecond representations
-of | return +a == +b; |
RegExps are compared by their source patterns and flags. | case '[object RegExp]':
- return a.source == b.source &&
- a.global == b.global &&
- a.multiline == b.multiline &&
- a.ignoreCase == b.ignoreCase;
- }
- if (typeof a != 'object' || typeof b != 'object') return false; |
Assume equality for cyclic structures. The algorithm for detecting cyclic
-structures is adapted from ES 5.1 section 15.12.3, abstract operation | var length = aStack.length;
- while (length--) { |
Linear search. Performance is inversely proportional to the number of -unique nested structures. | if (aStack[length] == a) return bStack[length] == b;
- } |
Add the first object to the stack of traversed objects. | aStack.push(a);
- bStack.push(b);
- var size = 0, result = true; |
Recursively compare objects and arrays. | if (className == '[object Array]') { |
Compare array lengths to determine if a deep comparison is necessary. | size = a.length;
- result = size == b.length;
- if (result) { |
Deep compare the contents, ignoring non-numeric properties. | while (size--) {
- if (!(result = eq(a[size], b[size], aStack, bStack))) break;
- }
- }
- } else { |
Objects with different constructors are not equivalent, but | var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
- _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
- return false;
- } |
Deep compare objects. | for (var key in a) {
- if (_.has(a, key)) { |
Count the expected number of properties. | size++; |
Deep compare each member. | if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
- }
- } |
Ensure that both objects contain the same number of properties. | if (result) {
- for (key in b) {
- if (_.has(b, key) && !(size--)) break;
- }
- result = !size;
- }
- } |
Remove the first object from the stack of traversed objects. | aStack.pop();
- bStack.pop();
- return result;
- }; |
Perform a deep comparison to check if two objects are equal. | _.isEqual = function(a, b) {
- return eq(a, b, [], []);
- }; |
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 (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
- for (var key in obj) if (_.has(obj, key)) return false;
- return true;
- }; |
Is a given value a DOM element? | _.isElement = function(obj) {
- return !!(obj && obj.nodeType === 1);
- }; |
Is a given value an array? -Delegates to ECMA5's native Array.isArray | _.isArray = nativeIsArray || function(obj) {
- return toString.call(obj) == '[object Array]';
- }; |
Is a given variable an object? | _.isObject = function(obj) {
- return obj === Object(obj);
- }; |
Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. | each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
- _['is' + name] = function(obj) {
- return toString.call(obj) == '[object ' + name + ']';
- };
- }); |
Define a fallback version of the method in browsers (ahem, IE), where -there isn't any inspectable "Arguments" type. | if (!_.isArguments(arguments)) {
- _.isArguments = function(obj) {
- return !!(obj && _.has(obj, 'callee'));
- };
- } |
Optimize | if (typeof (/./) !== 'function') {
- _.isFunction = function(obj) {
- return typeof obj === 'function';
- };
- } |
Is a given object a finite number? | _.isFinite = function(obj) {
- return _.isNumber(obj) && isFinite(obj);
- }; |
Is the given value | _.isNaN = function(obj) {
- return _.isNumber(obj) && obj != +obj;
- }; |
Is a given value a boolean? | _.isBoolean = function(obj) {
- return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
- }; |
Is a given value equal to null? | _.isNull = function(obj) {
- return obj === null;
- }; |
Is a given variable undefined? | _.isUndefined = function(obj) {
- return obj === void 0;
- }; |
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 hasOwnProperty.call(obj, key);
- }; |
Utility Functions | |
Run Underscore.js in noConflict mode, returning the | _.noConflict = function() {
- root._ = previousUnderscore;
- return this;
- }; |
Keep the identity function around for default iterators. | _.identity = function(value) {
- return value;
- }; |
Run a function n times. | _.times = function(n, iterator, context) {
- for (var i = 0; i < n; i++) iterator.call(context, i);
- }; |
Return a random integer between min and max (inclusive). | _.random = function(min, max) {
- if (max == null) {
- max = min;
- min = 0;
- }
- return min + (0 | Math.random() * (max - min + 1));
- }; |
List of HTML entities for escaping. | var entityMap = {
- escape: {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- '/': '/'
- }
- };
- entityMap.unescape = _.invert(entityMap.escape); |
Regexes containing the keys and values listed immediately above. | var entityRegexes = {
- escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
- unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
- }; |
Functions for escaping and unescaping strings to/from HTML interpolation. | _.each(['escape', 'unescape'], function(method) {
- _[method] = function(string) {
- if (string == null) return '';
- return ('' + string).replace(entityRegexes[method], function(match) {
- return entityMap[method][match];
- });
- };
- }); |
If the value of the named property is a function then invoke it; -otherwise, return it. | _.result = function(object, property) {
- if (object == null) return null;
- var value = object[property];
- return _.isFunction(value) ? value.call(object) : value;
- }; |
Add your own custom functions to the Underscore object. | _.mixin = function(obj) {
- each(_.functions(obj), function(name){
- var func = _[name] = obj[name];
- _.prototype[name] = function() {
- var args = [this._wrapped];
- push.apply(args, arguments);
- return result.call(this, func.apply(_, args));
- };
- });
- }; |
Generate a unique integer id (unique within the entire client session). -Useful for temporary DOM ids. | var idCounter = 0;
- _.uniqueId = function(prefix) {
- var id = idCounter++;
- return prefix ? prefix + id : id;
- }; |
By default, Underscore uses ERB-style template delimiters, change the -following template settings to use alternative delimiters. | _.templateSettings = {
- evaluate : /<%([\s\S]+?)%>/g,
- interpolate : /<%=([\s\S]+?)%>/g,
- escape : /<%-([\s\S]+?)%>/g
- }; |
When customizing | var noMatch = /(.)^/; |
Certain characters need to be escaped so that they can be put into a -string literal. | var escapes = {
- "'": "'",
- '\\': '\\',
- '\r': 'r',
- '\n': 'n',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; |
JavaScript micro-templating, similar to John Resig's implementation. -Underscore templating handles arbitrary delimiters, preserves whitespace, -and correctly escapes quotes within interpolated code. | _.template = function(text, data, settings) {
- settings = _.defaults({}, settings, _.templateSettings); |
Combine delimiters into one regular expression via alternation. | var matcher = new RegExp([
- (settings.escape || noMatch).source,
- (settings.interpolate || noMatch).source,
- (settings.evaluate || noMatch).source
- ].join('|') + '|$', 'g'); |
Compile the template source, escaping string literals appropriately. | var index = 0;
- var source = "__p+='";
- text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
- source += text.slice(index, offset)
- .replace(escaper, function(match) { return '\\' + escapes[match]; });
- source +=
- escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
- interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
- evaluate ? "';\n" + evaluate + "\n__p+='" : '';
- index = offset + match.length;
- });
- source += "';\n"; |
If a variable is not specified, place data values in local scope. | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-
- source = "var __t,__p='',__j=Array.prototype.join," +
- "print=function(){__p+=__j.call(arguments,'');};\n" +
- source + "return __p;\n";
-
- try {
- var render = new Function(settings.variable || 'obj', '_', source);
- } catch (e) {
- e.source = source;
- throw e;
- }
-
- if (data) return render(data, _);
- var template = function(data) {
- return render.call(this, data, _);
- }; |
Provide the compiled function source as a convenience for precompilation. | template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
-
- return template;
- }; |
Add a "chain" function, which will delegate to the wrapper. | _.chain = function(obj) {
- return _(obj).chain();
- }; |
OOP- -If Underscore is called as a function, it returns a wrapped object that -can be used OO-style. This wrapper holds altered versions of all the -underscore functions. Wrapped objects may be chained. | |
Helper function to continue chaining intermediate results. | var result = function(obj) {
- return this._chain ? _(obj).chain() : obj;
- }; |
Add all of the Underscore functions to the wrapper object. | _.mixin(_); |
Add all mutator Array functions to the wrapper. | each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- var obj = this._wrapped;
- method.apply(obj, arguments);
- if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
- return result.call(this, obj);
- };
- }); |
Add all accessor Array functions to the wrapper. | each(['concat', 'join', 'slice'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- return result.call(this, method.apply(this._wrapped, arguments));
- };
- });
-
- _.extend(_.prototype, { |
Start chaining a wrapped Underscore object. | chain: function() {
- this._chain = true;
- return this;
- }, |
Extracts the result from a wrapped and chained object. | value: function() {
- return this._wrapped;
- }
-
- });
-
-}).call(this);
-
- |
-
-
- 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. It's the - tie to go along with jQuery's tux, - and Backbone.js's suspenders. -
- -- Underscore provides 80-odd functions that support both the usual - functional suspects: map, select, invoke — - as well as more specialized helpers: function binding, javascript - templating, deep equality testing, and so on. It delegates to built-in - functions, if present, so modern browsers will use the - native implementations of forEach, map, reduce, - filter, every, some and indexOf. -
- -- A complete Test & Benchmark Suite - is included for your perusal. -
- -- You may also read through the annotated source code. -
- -- The project is - hosted on GitHub. - You can report bugs and discuss features on the - issues page, - on Freenode in the #documentcloud channel, - or send tweets to @documentcloud. -
- -- Underscore is an open-source component of DocumentCloud. -
- -Development Version (1.4.2) | -40kb, Uncompressed with Plentiful Comments | -
Production Version (1.4.2) | -4kb, Minified and Gzipped | -
- | |
Edge Version | -Unreleased, current master, use at your own risk | -
- each_.each(list, iterator, [context])
- Alias: forEach
-
- Iterates over a list of elements, yielding each in turn to an iterator
- function. The iterator is bound to the context object, if one is
- passed. Each invocation of iterator is called with three arguments:
- (element, index, list). If list is a JavaScript object, iterator's
- arguments will be (value, key, list). Delegates to the native
- forEach function if it exists.
-
-_.each([1, 2, 3], function(num){ alert(num); }); -=> alerts each number in turn... -_.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); }); -=> alerts each number in turn...- -
- map_.map(list, iterator, [context])
- Alias: collect
-
- Produces a new array of values by mapping each value in list
- through a transformation function (iterator). If the native map method
- exists, it will be used instead. If list is a JavaScript object,
- iterator's arguments will be (value, key, list).
-
-_.map([1, 2, 3], function(num){ return num * 3; }); -=> [3, 6, 9] -_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; }); -=> [3, 6, 9]- -
- reduce_.reduce(list, iterator, memo, [context])
- Aliases: inject, foldl
-
- Also known as inject and foldl, reduce boils down a
- list of values into a single value. Memo is the initial state
- of the reduction, and each successive step of it should be returned by
- iterator. The iterator is passed four arguments: the memo,
- then the value and index (or key) of the iteration,
- and finally a reference to the entire list.
-
-var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); -=> 6 -- -
- reduceRight_.reduceRight(list, iterator, memo, [context])
- Alias: foldr
-
- The right-associative version of reduce. Delegates to the
- JavaScript 1.8 version of reduceRight, if it exists. Foldr
- is not as useful in JavaScript as it would be in a language with lazy
- evaluation.
-
-var list = [[0, 1], [2, 3], [4, 5]]; -var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); -=> [4, 5, 2, 3, 0, 1] -- -
- find_.find(list, iterator, [context])
- Alias: detect
-
- Looks through each value in the list, returning the first one that
- passes a truth test (iterator). The function returns as
- soon as it finds an acceptable element, and doesn't traverse the
- entire list.
-
-var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); -=> 2 -- -
- filter_.filter(list, iterator, [context])
- Alias: select
-
- Looks through each value in the list, returning an array of all
- the values that pass a truth test (iterator). Delegates to the
- native filter method, if it exists.
-
-var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); -=> [2, 4, 6] -- -
- where_.where(list, properties)
-
- Looks through each value in the list, returning an array of all
- the values that contain all of the key-value pairs listed in properties.
-
-_.where(listOfPlays, {author: "Shakespeare", year: 1611}); -=> [{title: "Cymbeline", author: "Shakespeare", year: 1611}, - {title: "The Tempest", author: "Shakespeare", year: 1611}] -- -
- reject_.reject(list, iterator, [context])
-
- Returns the values in list without the elements that the truth
- test (iterator) passes. The opposite of filter.
-
-var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); -=> [1, 3, 5] -- -
- all_.all(list, iterator, [context])
- Alias: every
-
- Returns true if all of the values in the list pass the iterator
- truth test. Delegates to the native method every, if present.
-
-_.all([true, 1, null, 'yes'], _.identity); -=> false -- -
- any_.any(list, [iterator], [context])
- Alias: some
-
- Returns true if any of the values in the list pass the
- iterator truth test. Short-circuits and stops traversing the list
- if a true element is found. Delegates to the native method some,
- if present.
-
-_.any([null, 0, 'yes', false]); -=> true -- -
- contains_.contains(list, value)
- Alias: include
-
- Returns true if the value is present in the list.
- Uses indexOf internally, if list is an Array.
-
-_.contains([1, 2, 3], 3); -=> true -- -
- invoke_.invoke(list, methodName, [*arguments])
-
- Calls the method named by methodName on each value in the list.
- Any extra arguments passed to invoke will be forwarded on to the
- method invocation.
-
-_.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); -=> [[1, 5, 7], [1, 2, 3]] -- -
- pluck_.pluck(list, propertyName)
-
- A convenient version of what is perhaps the most common use-case for
- map: extracting a list of property values.
-
-var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; -_.pluck(stooges, 'name'); -=> ["moe", "larry", "curly"] -- -
- max_.max(list, [iterator], [context])
-
- Returns the maximum value in list. If iterator is passed,
- it will be used on each value to generate the criterion by which the
- value is ranked.
-
-var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; -_.max(stooges, function(stooge){ return stooge.age; }); -=> {name : 'curly', age : 60}; -- -
- min_.min(list, [iterator], [context])
-
- Returns the minimum value in list. If iterator is passed,
- it will be used on each value to generate the criterion by which the
- value is ranked.
-
-var numbers = [10, 5, 100, 2, 1000]; -_.min(numbers); -=> 2 -- -
- sortBy_.sortBy(list, iterator, [context])
-
- Returns a sorted copy of list, ranked in ascending order by the
- results of running each value through iterator. Iterator may
- also be the string name of the property to sort by (eg. length).
-
-_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); -=> [5, 4, 6, 3, 1, 2] -- -
- groupBy_.groupBy(list, iterator)
-
- Splits a collection into sets, grouped by the result of running each
- value through iterator. If iterator is a string instead of
- a function, groups by the property named by iterator on each of
- the values.
-
-_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); -=> {1: [1.3], 2: [2.1, 2.4]} - -_.groupBy(['one', 'two', 'three'], 'length'); -=> {3: ["one", "two"], 5: ["three"]} -- -
- countBy_.countBy(list, iterator)
-
- Sorts a list into groups and returns a count for the number of objects
- in each group.
- Similar to groupBy, but instead of returning a list of values,
- returns a count for the number of values in that group.
-
-_.countBy([1, 2, 3, 4, 5], function(num) { - return num % 2 == 0 ? 'even' : 'odd'; -}); -=> {odd: 3, even: 2} -- -
- shuffle_.shuffle(list)
-
- Returns a shuffled copy of the list, using a version of the
- Fisher-Yates shuffle.
-
-_.shuffle([1, 2, 3, 4, 5, 6]); -=> [4, 1, 6, 3, 5, 2] -- -
- toArray_.toArray(list)
-
- Converts the list (anything that can be iterated over), into a
- real Array. Useful for transmuting the arguments object.
-
-(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); -=> [2, 3, 4] -- -
- size_.size(list)
-
- Return the number of values in the list.
-
-_.size({one : 1, two : 2, three : 3}); -=> 3 -- -
- - Note: All array functions will also work on the arguments object. - However, Underscore functions are not designed to work on "sparse" arrays. - -
- -
- first_.first(array, [n])
- Alias: head, take
-
- Returns the first element of an array. Passing n will
- return the first n elements of the array.
-
-_.first([5, 4, 3, 2, 1]); -=> 5 -- -
- initial_.initial(array, [n])
-
- Returns everything but the last entry of the array. Especially useful on
- the arguments object. Pass n to exclude the last n elements
- from the result.
-
-_.initial([5, 4, 3, 2, 1]); -=> [5, 4, 3, 2] -- -
- last_.last(array, [n])
-
- Returns the last element of an array. Passing n will return
- the last n elements of the array.
-
-_.last([5, 4, 3, 2, 1]); -=> 1 -- -
- rest_.rest(array, [index])
- Alias: tail, drop
-
- Returns the rest of the elements in an array. Pass an index
- to return the values of the array from that index onward.
-
-_.rest([5, 4, 3, 2, 1]); -=> [4, 3, 2, 1] -- -
- compact_.compact(array)
-
- Returns a copy of the array with all falsy values removed.
- In JavaScript, false, null, 0, "",
- undefined and NaN are all falsy.
-
-_.compact([0, 1, false, 2, '', 3]); -=> [1, 2, 3] -- -
- flatten_.flatten(array, [shallow])
-
- Flattens a nested array (the nesting can be to any depth). If you
- pass shallow, the array will only be flattened a single level.
-
-_.flatten([1, [2], [3, [[4]]]]); -=> [1, 2, 3, 4]; - -_.flatten([1, [2], [3, [[4]]]], true); -=> [1, 2, 3, [[4]]]; -- -
- without_.without(array, [*values])
-
- Returns a copy of the array with all instances of the values
- removed.
-
-_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); -=> [2, 3, 4] -- -
- union_.union(*arrays)
-
- Computes the union of the passed-in arrays: the list of unique items,
- in order, that are present in one or more of the arrays.
-
-_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); -=> [1, 2, 3, 101, 10] -- -
- intersection_.intersection(*arrays)
-
- Computes the list of values that are the intersection of all the arrays.
- Each value in the result is present in each of the arrays.
-
-_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); -=> [1, 2] -- -
- difference_.difference(array, *others)
-
- Similar to without, but returns the values from array that
- are not present in the other arrays.
-
-_.difference([1, 2, 3, 4, 5], [5, 2, 10]); -=> [1, 3, 4] -- -
- uniq_.uniq(array, [isSorted], [iterator])
- Alias: unique
-
- Produces a duplicate-free version of the array, using === to test
- object equality. If you know in advance that the array is sorted,
- passing true for isSorted will run a much faster algorithm.
- If you want to compute unique items based on a transformation, pass an
- iterator function.
-
-_.uniq([1, 2, 1, 3, 1, 4]); -=> [1, 2, 3, 4] -- -
- zip_.zip(*arrays)
-
- Merges together the values of each of the arrays with the
- values at the corresponding position. Useful when you have separate
- data sources that are coordinated through matching array indexes.
- If you're working with a matrix of nested arrays, zip.apply
- can transpose the matrix in a similar fashion.
-
-_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); -=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]] -- -
- object_.object(list, [values])
-
- Converts arrays into objects. Pass either a single list of
- [key, value] pairs, or a list of keys, and a list of values.
-
-_.object(['moe', 'larry', 'curly'], [30, 40, 50]); -=> {moe: 30, larry: 40, curly: 50} - -_.object([['moe', 30], ['larry', 40], ['curly', 50]]); -=> {moe: 30, larry: 40, curly: 50} -- -
- indexOf_.indexOf(array, value, [isSorted])
-
- Returns the index at which value can be found in the array,
- or -1 if value is not present in the array. Uses the native
- indexOf function unless it's missing. If you're working with a
- large array, and you know that the array is already sorted, pass true
- for isSorted to use a faster binary search ... or, pass a number as
- the third argument in order to look for the first matching value in the
- array after the given index.
-
-_.indexOf([1, 2, 3], 2); -=> 1 -- -
- lastIndexOf_.lastIndexOf(array, value, [fromIndex])
-
- Returns the index of the last occurrence of value in the array,
- or -1 if value is not present. Uses the native lastIndexOf
- function if possible. Pass fromIndex to start your search at a
- given index.
-
-_.lastIndexOf([1, 2, 3, 1, 2, 3], 2); -=> 4 -- -
- sortedIndex_.sortedIndex(list, value, [iterator])
-
- Uses a binary search to determine the index at which the value
- should be inserted into the list in order to maintain the list's
- sorted order. If an iterator is passed, it will be used to compute
- the sort ranking of each value, including the value you pass.
-
-_.sortedIndex([10, 20, 30, 40, 50], 35); -=> 3 -- -
- range_.range([start], stop, [step])
-
- A function to create flexibly-numbered lists of integers, handy for
- each and map loops. start, if omitted, defaults
- to 0; step defaults to 1. Returns a list of integers
- from start to stop, incremented (or decremented) by step,
- exclusive.
-
-_.range(10); -=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -_.range(1, 11); -=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -_.range(0, 30, 5); -=> [0, 5, 10, 15, 20, 25] -_.range(0, -10, -1); -=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] -_.range(0); -=> [] -- -
- bind_.bind(function, object, [*arguments])
-
- Bind a function to an object, meaning that whenever
- the function is called, the value of this will be the object.
- Optionally, bind arguments to the function to pre-fill them,
- also known as partial application.
-
-var func = function(greeting){ return greeting + ': ' + this.name }; -func = _.bind(func, {name : 'moe'}, 'hi'); -func(); -=> 'hi: moe' -- -
- bindAll_.bindAll(object, [*methodNames])
-
- Binds a number of methods on the object, specified by
- methodNames, to be run in the context of that object whenever they
- are invoked. Very handy for binding functions that are going to be used
- as event handlers, which would otherwise be invoked with a fairly useless
- this. If no methodNames are provided, all of the object's
- function properties will be bound to it.
-
-var buttonView = { - label : 'underscore', - onClick : function(){ alert('clicked: ' + this.label); }, - onHover : function(){ console.log('hovering: ' + this.label); } -}; -_.bindAll(buttonView); -jQuery('#underscore_button').bind('click', buttonView.onClick); -=> When the button is clicked, this.label will have the correct value... -- -
- memoize_.memoize(function, [hashFunction])
-
- Memoizes a given function by caching the computed result. Useful
- for speeding up slow-running computations. If passed an optional
- hashFunction, it will be used to compute the hash key for storing
- the result, based on the arguments to the original function. The default
- hashFunction just uses the first argument to the memoized function
- as the key.
-
-var fibonacci = _.memoize(function(n) { - return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); -}); -- -
- delay_.delay(function, wait, [*arguments])
-
- Much like setTimeout, invokes function after wait
- milliseconds. If you pass the optional arguments, they will be
- forwarded on to the function when it is invoked.
-
-var log = _.bind(console.log, console); -_.delay(log, 1000, 'logged later'); -=> 'logged later' // Appears after one second. -- -
- defer_.defer(function, [*arguments])
-
- Defers invoking the function until the current call stack has cleared,
- similar to using setTimeout with a delay of 0. Useful for performing
- expensive computations or HTML rendering in chunks without blocking the UI thread
- from updating. If you pass the optional arguments, they will be
- forwarded on to the function when it is invoked.
-
-_.defer(function(){ alert('deferred'); }); -// Returns from the function before the alert runs. -- -
- throttle_.throttle(function, wait)
-
- Creates and returns a new, throttled version of the passed function,
- that, when invoked repeatedly, will only actually call the original function
- at most once per every wait
- milliseconds. Useful for rate-limiting events that occur faster than you
- can keep up with.
-
-var throttled = _.throttle(updatePosition, 100); -$(window).scroll(throttled); -- -
- debounce_.debounce(function, wait, [immediate])
-
- Creates and returns a new debounced version of the passed function that
- will postpone its execution until after
- wait milliseconds have elapsed since the last time it
- was invoked. Useful for implementing behavior that should only happen
- after the input has stopped arriving. For example: rendering a
- preview of a Markdown comment, recalculating a layout after the window
- has stopped being resized, and so on.
-
- Pass true for the immediate parameter to cause - debounce to trigger the function on the leading instead of the - trailing edge of the wait interval. Useful in circumstances like - preventing accidental double-clicks on a "submit" button from firing a - second time. -
- --var lazyLayout = _.debounce(calculateLayout, 300); -$(window).resize(lazyLayout); -- -
- once_.once(function)
-
- Creates a version of the function that can only be called one time.
- Repeated calls to the modified function will have no effect, returning
- the value from the original call. Useful for initialization functions,
- instead of having to set a boolean flag and then check it later.
-
-var initialize = _.once(createApplication); -initialize(); -initialize(); -// Application is only created once. -- -
- after_.after(count, function)
-
- Creates a version of the function that will only be run after first
- being called count times. Useful for grouping asynchronous responses,
- where you want to be sure that all the async calls have finished, before
- proceeding.
-
-var renderNotes = _.after(notes.length, render); -_.each(notes, function(note) { - note.asyncSave({success: renderNotes}); -}); -// renderNotes is run once, after all notes have saved. -- -
- wrap_.wrap(function, wrapper)
-
- Wraps the first function inside of the wrapper function,
- passing it as the first argument. This allows the wrapper to
- execute code before and after the function runs, adjust the arguments,
- and execute it conditionally.
-
-var hello = function(name) { return "hello: " + name; }; -hello = _.wrap(hello, function(func) { - return "before, " + func("moe") + ", after"; -}); -hello(); -=> 'before, hello: moe, after' -- -
- compose_.compose(*functions)
-
- Returns the composition of a list of functions, where each function
- consumes the return value of the function that follows. In math terms,
- composing the functions f(), g(), and h() produces
- f(g(h())).
-
-var greet = function(name){ return "hi: " + name; }; -var exclaim = function(statement){ return statement + "!"; }; -var welcome = _.compose(exclaim, greet); -welcome('moe'); -=> 'hi: moe!' -- -
- keys_.keys(object)
-
- Retrieve all the names of the object's properties.
-
-_.keys({one : 1, two : 2, three : 3}); -=> ["one", "two", "three"] -- -
- values_.values(object)
-
- Return all of the values of the object's 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({one: 1, two: 2, three: 3}); -=> [["one", 1], ["two", 2], ["three", 3]] -- -
- invert_.invert(object)
-
- 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"}; -- -
- functions_.functions(object)
- Alias: methods
-
- Returns a sorted list of the names of every method in an object —
- that is to say, the name of every function property of the object.
-
-_.functions(_); -=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ... -- -
- extend_.extend(destination, *sources)
-
- Copy all of the properties in the source objects over to the
- destination object, and return the destination object.
- 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, filtered to only have values for
- the whitelisted keys (or array of valid keys).
-
-_.pick({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age'); -=> {name : 'moe', age : 50} -- -
- omit_.omit(object, *keys)
-
- Return a copy of the object, filtered to omit the blacklisted
- keys (or array of keys).
-
-_.omit({name : 'moe', age : 50, userid : 'moe1'}, 'userid'); -=> {name : 'moe', age : 50} -- -
- defaults_.defaults(object, *defaults)
-
- Fill in null and undefined properties in object with values from the
- defaults objects, and return the object. As soon as the
- property is filled, further defaults will have no effect.
-
-var iceCream = {flavor : "chocolate"}; -_.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"}); -=> {flavor : "chocolate", sprinkles : "lots"} -- -
- clone_.clone(object)
-
- Create a shallow-copied clone of the object. Any nested objects
- or arrays will be copied by reference, not duplicated.
-
-_.clone({name : 'moe'}); -=> {name : 'moe'}; -- -
- tap_.tap(object, interceptor)
-
- 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] -- -
- has_.has(object, 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 -- -
- isEqual_.isEqual(object, other)
-
- Performs an optimized deep comparison between the two objects, to determine
- if they should be considered equal.
-
-var moe = {name : 'moe', luckyNumbers : [13, 27, 34]}; -var clone = {name : 'moe', luckyNumbers : [13, 27, 34]}; -moe == clone; -=> false -_.isEqual(moe, clone); -=> true -- -
- isEmpty_.isEmpty(object)
-
- Returns true if object contains no values.
-
-_.isEmpty([1, 2, 3]); -=> false -_.isEmpty({}); -=> true -- -
- isElement_.isElement(object)
-
- Returns true if object is a DOM element.
-
-_.isElement(jQuery('body')[0]); -=> true -- -
- isArray_.isArray(object)
-
- Returns true if object is an Array.
-
-(function(){ return _.isArray(arguments); })(); -=> false -_.isArray([1,2,3]); -=> true -- -
- isObject_.isObject(value)
-
- 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)
-
- Returns true if object is an Arguments object.
-
-(function(){ return _.isArguments(arguments); })(1, 2, 3); -=> true -_.isArguments([1,2,3]); -=> false -- -
- isFunction_.isFunction(object)
-
- Returns true if object is a Function.
-
-_.isFunction(alert); -=> true -- -
- isString_.isString(object)
-
- Returns true if object is a String.
-
-_.isString("moe"); -=> true -- -
- isNumber_.isNumber(object)
-
- Returns true if object is a Number (including NaN).
-
-_.isNumber(8.4 * 5); -=> true -- -
- isFinite_.isFinite(object)
-
- Returns true if object is a finite Number.
-
-_.isFinite(-101); -=> true - -_.isFinite(-Infinity); -=> false -- -
- isBoolean_.isBoolean(object)
-
- Returns true if object is either true or false.
-
-_.isBoolean(null); -=> false -- -
- isDate_.isDate(object)
-
- Returns true if object is a Date.
-
-_.isDate(new Date()); -=> true -- -
- isRegExp_.isRegExp(object)
-
- Returns true if object is a RegExp.
-
-_.isRegExp(/moe/); -=> true -- -
- isNaN_.isNaN(object)
-
- Returns true if object is NaN.
Note: this is not
- the same as the native isNaN function, which will also return
- true if the variable is undefined.
-
-_.isNaN(NaN); -=> true -isNaN(undefined); -=> true -_.isNaN(undefined); -=> false -- -
- isNull_.isNull(object)
-
- Returns true if the value of object is null.
-
-_.isNull(null); -=> true -_.isNull(undefined); -=> false -- -
- isUndefined_.isUndefined(value)
-
- Returns true if value is undefined.
-
-_.isUndefined(window.missingVariable); -=> true -- -
- noConflict_.noConflict()
-
- Give control of the "_" variable back to its previous owner. Returns
- a reference to the Underscore object.
-
-var underscore = _.noConflict();- -
- identity_.identity(value)
-
- Returns the same value that is used as the argument. In math:
- f(x) = x
- This function looks useless, but is used throughout Underscore as
- a default iterator.
-
-var moe = {name : 'moe'}; -moe === _.identity(moe); -=> true- -
- times_.times(n, iterator, [context])
-
- Invokes the given iterator function n times. Each invocation of
- iterator is called with an index argument.
-
-_(3).times(function(n){ genie.grantWishNumber(n); });- -
- random_.random(min, max)
-
- Returns a random integer between min and max, inclusive.
- If you only pass one argument, it will return a number between 0
- and that number.
-
-_.random(0, 100); -=> 42- -
- mixin_.mixin(object)
-
- Allows you to extend Underscore with your own utility functions. Pass
- a hash of {name: function} definitions to have your functions
- added to the Underscore object, as well as the OOP wrapper.
-
-_.mixin({ - capitalize : function(string) { - return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase(); - } -}); -_("fabio").capitalize(); -=> "Fabio" -- -
- uniqueId_.uniqueId([prefix])
-
- Generate a globally-unique id for client-side models or DOM elements
- that need one. If prefix is passed, the id will be appended to it.
- Without prefix, returns an integer.
-
-_.uniqueId('contact_'); -=> 'contact_104'- -
- escape_.escape(string)
-
- Escapes a string for insertion into HTML, replacing
- &, <, >, ", ', and / characters.
-
-_.escape('Curly, Larry & Moe'); -=> "Curly, Larry & Moe"- -
- result_.result(object, property)
-
- If the value of the named property is a function then invoke it; otherwise, return it.
-
-var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }}; -_.result(object, 'cheese'); -=> "crumpets" -_.result(object, 'stuff'); -=> "nonsense"- -
- template_.template(templateString, [data], [settings])
-
- Compiles JavaScript templates into functions that can be evaluated
- for rendering. Useful for rendering complicated bits of HTML from JSON
- data sources. Template functions can both interpolate variables, using
- <%= … %>, as well as execute arbitrary JavaScript code, with
- <% … %>. If you wish to interpolate a value, and have
- it be HTML-escaped, use <%- … %> When you evaluate a template function, pass in a
- data object that has properties corresponding to the template's free
- variables. If you're writing a one-off, you can pass the data
- object as the second parameter to template in order to render
- immediately instead of returning a template function. The settings argument
- should be a hash containing any _.templateSettings that should be overridden.
-
-var compiled = _.template("hello: <%= name %>"); -compiled({name : 'moe'}); -=> "hello: moe" - -var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>"; -_.template(list, {people : ['moe', 'curly', 'larry']}); -=> "<li>moe</li><li>curly</li><li>larry</li>" - -var template = _.template("<b><%- value %></b>"); -template({value : '<script>'}); -=> "<b><script></b>"- -
- You can also use print from within JavaScript code. This is - sometimes more convenient than using <%= ... %>. -
- --var compiled = _.template("<% print('Hello ' + epithet); %>"); -compiled({epithet: "stooge"}); -=> "Hello stooge."- -
- If ERB-style delimiters aren't your cup of tea, you can change Underscore's - template settings to use different symbols to set off interpolated code. - Define an interpolate regex to match expressions that should be - interpolated verbatim, an escape regex to match expressions that should - be inserted after being HTML escaped, and an evaluate regex to match - expressions that should be evaluated without insertion into the resulting - string. You may define or omit any combination of the three. - For example, to perform - Mustache.js - style templating: -
- --_.templateSettings = { - interpolate : /\{\{(.+?)\}\}/g -}; - -var template = _.template("Hello {{ name }}!"); -template({name : "Mustache"}); -=> "Hello Mustache!"- -
- By default, template places the values from your data in the local scope - via the with statement. However, you can specify a single variable name - with the variable setting. This can significantly improve the speed - at which a template is able to render. -
- --_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'}); -=> "Using 'with': no"- -
- Precompiling your templates can be a big help when debugging errors you can't - reproduce. This is because precompiled templates can provide line numbers and - a stack trace, something that is not possible when compiling templates on the client. - The source property is available on the compiled template - function for easy precompilation. -
- -<script> - JST.project = <%= _.template(jstText).source %>; -</script>- - -
- You can use Underscore in either an object-oriented or a functional style, - depending on your preference. The following two lines of code are - identical ways to double a list of numbers. -
- --_.map([1, 2, 3], function(n){ return n * 2; }); -_([1, 2, 3]).map(function(n){ return n * 2; });- -
- Calling chain will cause all future method calls to return - wrapped objects. When you've finished the computation, use - value to retrieve the final value. Here's an example of chaining - together a map/flatten/reduce, in order to get the word count of - every word in a song. -
- --var lyrics = [ - {line : 1, words : "I'm a lumberjack and I'm okay"}, - {line : 2, words : "I sleep all night and I work all day"}, - {line : 3, words : "He's a lumberjack and he's okay"}, - {line : 4, words : "He sleeps all night and he works all day"} -]; - -_.chain(lyrics) - .map(function(line) { return line.words.split(' '); }) - .flatten() - .reduce(function(counts, word) { - counts[word] = (counts[word] || 0) + 1; - return counts; -}, {}).value(); - -=> {lumberjack : 2, all : 4, night : 2 ... }- -
- In addition, the - Array prototype's methods - are proxied through the chained Underscore object, so you can slip a - reverse or a push into your chain, and continue to - modify the array. -
- -
- chain_.chain(obj)
-
- Returns a wrapped object. Calling methods on this object will continue
- to return wrapped objects until value is used.
-
-var stooges = [{name : 'curly', age : 25}, {name : 'moe', age : 21}, {name : 'larry', age : 23}]; -var youngest = _.chain(stooges) - .sortBy(function(stooge){ return stooge.age; }) - .map(function(stooge){ return stooge.name + ' is ' + stooge.age; }) - .first() - .value(); -=> "moe is 21" -- -
- value_(obj).value()
-
- Extracts the value of a wrapped object.
-
-_([1, 2, 3]).value(); -=> [1, 2, 3] -- -
- The Underscore documentation is also available in - Simplified Chinese. -
- -- Underscore.lua, - a Lua port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - (source) -
- -- Underscore.m, an Objective-C port - of many of the Underscore.js functions, using a syntax that encourages - chaining. - (source) -
- -- _.m, an alternative - Objective-C port that tries to stick a little closer to the original - Underscore.js API. - (source) -
- -- Underscore.php, - a PHP port of the functions that are applicable in both languages. - Includes OOP-wrapping and chaining. - (source) -
- -- Underscore-perl, - a Perl port of many of the Underscore.js functions, - aimed at on Perl hashes and arrays. - (source) -
- -- Underscore.cfc, - a Coldfusion port of many of the Underscore.js functions. - (source) -
- -- Underscore.string, - an Underscore extension that adds functions for string-manipulation: - trim, startsWith, contains, capitalize, - reverse, sprintf, and more. -
- -- Ruby's Enumerable module. -
- -- Prototype.js, which provides - JavaScript with collection functions in the manner closest to Ruby's Enumerable. -
- -- Oliver Steele's - Functional JavaScript, - which includes comprehensive higher-order function support as well as string lambdas. -
- -- Michael Aufreiter's Data.js, - a data manipulation + persistence library for JavaScript. -
- -- Python's itertools. -
- -
- 1.4.2 — Oct. 1, 2012 — Diff
-
- 1.4.1 — Oct. 1, 2012 — Diff
-
- 1.4.0 — Sept. 27, 2012 — Diff
-
- 1.3.3 — April 10, 2012
-
- 1.3.1 — Jan. 23, 2012
-
- 1.3.0 — Jan. 11, 2012
-
- 1.2.4 — Jan. 4, 2012
-
- 1.2.3 — Dec. 7, 2011
-
- 1.2.2 — Nov. 14, 2011
-
- 1.2.1 — Oct. 24, 2011
-
- 1.2.0 — Oct. 5, 2011
-
- 1.1.7 — July 13, 2011
- Added _.groupBy, which aggregates a collection into groups of like items.
- Added _.union and _.difference, to complement the
- (re-named) _.intersection.
- Various improvements for support of sparse arrays.
- _.toArray now returns a clone, if directly passed an array.
- _.functions now also returns the names of functions that are present
- in the prototype chain.
-
- 1.1.6 — April 18, 2011
- Added _.after, which will return a function that only runs after
- first being called a specified number of times.
- _.invoke can now take a direct function reference.
- _.every now requires an iterator function to be passed, which
- mirrors the ECMA5 API.
- _.extend no longer copies keys when the value is undefined.
- _.bind now errors when trying to bind an undefined value.
-
- 1.1.5 — Mar 20, 2011
- Added an _.defaults function, for use merging together JS objects
- representing default options.
- Added an _.once function, for manufacturing functions that should
- only ever execute a single time.
- _.bind now delegates to the native ECMAScript 5 version,
- where available.
- _.keys now throws an error when used on non-Object values, as in
- ECMAScript 5.
- Fixed a bug with _.keys when used over sparse arrays.
-
- 1.1.4 — Jan 9, 2011
- Improved compliance with ES5's Array methods when passing null
- as a value. _.wrap now correctly sets this for the
- wrapped function. _.indexOf now takes an optional flag for
- finding the insertion index in an array that is guaranteed to already
- be sorted. Avoiding the use of .callee, to allow _.isArray
- to work properly in ES5's strict mode.
-
- 1.1.3 — Dec 1, 2010
- In CommonJS, Underscore may now be required with just:
- var _ = require("underscore").
- Added _.throttle and _.debounce functions.
- Removed _.breakLoop, in favor of an ECMA5-style un-break-able
- each implementation — this removes the try/catch, and you'll now have
- better stack traces for exceptions that are thrown within an Underscore iterator.
- Improved the isType family of functions for better interoperability
- with Internet Explorer host objects.
- _.template now correctly escapes backslashes in templates.
- Improved _.reduce compatibility with the ECMA5 version:
- if you don't pass an initial value, the first item in the collection is used.
- _.each no longer returns the iterated collection, for improved
- consistency with ES5's forEach.
-
- 1.1.2
- Fixed _.contains, which was mistakenly pointing at
- _.intersect instead of _.include, like it should
- have been. Added _.unique as an alias for _.uniq.
-
- 1.1.1
- Improved the speed of _.template, and its handling of multiline
- interpolations. Ryan Tenney contributed optimizations to many Underscore
- functions. An annotated version of the source code is now available.
-
- 1.1.0
- The method signature of _.reduce has been changed to match
- the ECMAScript 5 signature, instead of the Ruby/Prototype.js version.
- This is a backwards-incompatible change. _.template may now be
- called with no arguments, and preserves whitespace. _.contains
- is a new alias for _.include.
-
- 1.0.4
- Andri Möll contributed the _.memoize
- function, which can be used to speed up expensive repeated computations
- by caching the results.
-
- 1.0.3
- Patch that makes _.isEqual return false if any property
- of the compared object has a NaN value. Technically the correct
- thing to do, but of questionable semantics. Watch out for NaN comparisons.
-
- 1.0.2
- Fixes _.isArguments in recent versions of Opera, which have
- arguments objects as real Arrays.
-
- 1.0.1
- Bugfix for _.isEqual, when comparing two objects with the same
- number of undefined keys, but with different names.
-
- 1.0.0
- Things have been stable for many months now, so Underscore is now
- considered to be out of beta, at 1.0. Improvements since 0.6
- include _.isBoolean, and the ability to have _.extend
- take multiple source objects.
-
- 0.6.0
- Major release. Incorporates a number of
- Mile Frawley's refactors for
- safer duck-typing on collection functions, and cleaner internals. A new
- _.mixin method that allows you to extend Underscore with utility
- functions of your own. Added _.times, which works the same as in
- Ruby or Prototype.js. Native support for ECMAScript 5's Array.isArray,
- and Object.keys.
-
- 0.5.8
- Fixed Underscore's collection functions to work on
- NodeLists and
- HTMLCollections
- once more, thanks to
- Justin Tulloss.
-
- 0.5.7
- A safer implementation of _.isArguments, and a
- faster _.isNumber,
thanks to
- Jed Schmidt.
-
- 0.5.6
- Customizable delimiters for _.template, contributed by
- Noah Sloan.
-
- 0.5.5
- Fix for a bug in MobileSafari's OOP-wrapper, with the arguments object.
-
- 0.5.4
- Fix for multiple single quotes within a template string for
- _.template. See:
- Rick Strahl's blog post.
-
- 0.5.2
- New implementations of isArray, isDate, isFunction,
- isNumber, isRegExp, and isString, thanks to
- a suggestion from
- Robert Kieffer.
- Instead of doing Object#toString
- comparisons, they now check for expected properties, which is less safe,
- but more than an order of magnitude faster. Most other Underscore
- functions saw minor speed improvements as a result.
- Evgeniy Dolzhenko
- contributed _.tap,
- similar to Ruby 1.9's,
- which is handy for injecting side effects (like logging) into chained calls.
-
- 0.5.1
- Added an _.isArguments function. Lots of little safety checks
- and optimizations contributed by
- Noah Sloan and
- Andri Möll.
-
- 0.5.0
- [API Changes] _.bindAll now takes the context object as
- its first parameter. If no method names are passed, all of the context
- object's methods are bound to it, enabling chaining and easier binding.
- _.functions now takes a single argument and returns the names
- of its Function properties. Calling _.functions(_) will get you
- the previous behavior.
- Added _.isRegExp so that isEqual can now test for RegExp equality.
- All of the "is" functions have been shrunk down into a single definition.
- Karl Guertin contributed patches.
-
- 0.4.7
- Added isDate, isNaN, and isNull, for completeness.
- Optimizations for isEqual when checking equality between Arrays
- or Dates. _.keys is now 25%–2X faster (depending on your
- browser) which speeds up the functions that rely on it, such as _.each.
-
- 0.4.6
- Added the range function, a port of the
- Python
- function of the same name, for generating flexibly-numbered lists
- of integers. Original patch contributed by
- Kirill Ishanov.
-
- 0.4.5
- Added rest for Arrays and arguments objects, and aliased
- first as head, and rest as tail,
- thanks to Luke Sutton's patches.
- Added tests ensuring that all Underscore Array functions also work on
- arguments objects.
-
- 0.4.4
- Added isString, and isNumber, for consistency. Fixed
- _.isEqual(NaN, NaN) to return true (which is debatable).
-
- 0.4.3
- Started using the native StopIteration object in browsers that support it.
- Fixed Underscore setup for CommonJS environments.
-
- 0.4.2
- Renamed the unwrapping function to value, for clarity.
-
- 0.4.1
- Chained Underscore objects now support the Array prototype methods, so
- that you can perform the full range of operations on a wrapped array
- without having to break your chain. Added a breakLoop method
- to break in the middle of any Underscore iteration. Added an
- isEmpty function that works on arrays and objects.
-
- 0.4.0
- All Underscore functions can now be called in an object-oriented style,
- like so: _([1, 2, 3]).map(...);. Original patch provided by
- Marc-André Cournoyer.
- Wrapped objects can be chained through multiple
- method invocations. A functions method
- was added, providing a sorted list of all the functions in Underscore.
-
- 0.3.3
- Added the JavaScript 1.8 function reduceRight. Aliased it
- as foldr, and aliased reduce as foldl.
-
- 0.3.2
- Now runs on stock Rhino
- interpreters with: load("underscore.js").
- Added identity as a utility function.
-
- 0.3.1
- All iterators are now passed in the original collection as their third
- argument, the same as JavaScript 1.6's forEach. Iterating over
- objects is now called with (value, key, collection), for details
- see _.each.
-
- 0.3.0
- Added Dmitry Baranovskiy's
- comprehensive optimizations, merged in
- Kris Kowal's patches to make Underscore
- CommonJS and
- Narwhal compliant.
-
- 0.2.0
- Added compose and lastIndexOf, renamed inject to
- reduce, added aliases for inject, filter,
- every, some, and forEach.
-
- 0.1.1
- Added noConflict, so that the "Underscore" object can be assigned to
- other variables.
-
- 0.1.0
- Initial release of Underscore.js.
-
-
-
-
-
- A representative sample of the functions are benchmarked here, to provide
- a sense of how fast they might run in different browsers.
- Each iteration runs on an array of 1000 elements.
- For example, the 'intersection' test measures the number of times you can
- find the intersection of two thousand-element arrays in one second.
-
Just some text. Hey, I know this is silly but it aids consistency.
Just some text. Hey, I know this is silly but it aids consistency.