underscore-source 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
|
|
1
1
|
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
|
2
|
-
// Underscore is freely distributable under the
|
3
|
-
// Portions of Underscore are inspired
|
2
|
+
// Underscore is freely distributable under the MIT license.
|
3
|
+
// Portions of Underscore are inspired or borrowed from Prototype,
|
4
4
|
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
5
5
|
// For all details and documentation:
|
6
6
|
// http://documentcloud.github.com/underscore
|
@@ -19,9 +19,6 @@
|
|
19
19
|
// Establish the object that gets thrown to break out of a loop iteration.
|
20
20
|
var breaker = typeof StopIteration !== 'undefined' ? StopIteration : '__break__';
|
21
21
|
|
22
|
-
// Quick regexp-escaping function, because JS doesn't have a `RegExp.escape()`.
|
23
|
-
var escapeRegExp = function(s) { return s.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); };
|
24
|
-
|
25
22
|
// Save bytes in the minified (but not gzipped) version:
|
26
23
|
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
|
27
24
|
|
@@ -57,15 +54,15 @@
|
|
57
54
|
root._ = _;
|
58
55
|
|
59
56
|
// Current version.
|
60
|
-
_.VERSION = '1.1.
|
57
|
+
_.VERSION = '1.1.2';
|
61
58
|
|
62
59
|
// Collection Functions
|
63
60
|
// --------------------
|
64
61
|
|
65
|
-
// The cornerstone, an `each` implementation
|
62
|
+
// The cornerstone, an `each` implementation, aka `forEach`.
|
66
63
|
// Handles objects implementing `forEach`, arrays, and raw objects.
|
67
64
|
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
68
|
-
var each = _.forEach = function(obj, iterator, context) {
|
65
|
+
var each = _.each = _.forEach = function(obj, iterator, context) {
|
69
66
|
try {
|
70
67
|
if (nativeForEach && obj.forEach === nativeForEach) {
|
71
68
|
obj.forEach(iterator, context);
|
@@ -95,7 +92,7 @@
|
|
95
92
|
|
96
93
|
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
97
94
|
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
98
|
-
_.reduce = function(obj, iterator, memo, context) {
|
95
|
+
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
99
96
|
if (nativeReduce && obj.reduce === nativeReduce) {
|
100
97
|
if (context) iterator = _.bind(iterator, context);
|
101
98
|
return obj.reduce(iterator, memo);
|
@@ -106,19 +103,19 @@
|
|
106
103
|
return memo;
|
107
104
|
};
|
108
105
|
|
109
|
-
// The right-associative version of reduce, also known as `foldr`.
|
110
|
-
// Delegates to **ECMAScript 5**'s native reduceRight if available.
|
111
|
-
_.reduceRight = function(obj, iterator, memo, context) {
|
106
|
+
// The right-associative version of reduce, also known as `foldr`.
|
107
|
+
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
108
|
+
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
112
109
|
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
113
110
|
if (context) iterator = _.bind(iterator, context);
|
114
111
|
return obj.reduceRight(iterator, memo);
|
115
112
|
}
|
116
|
-
var reversed = _.
|
113
|
+
var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
|
117
114
|
return _.reduce(reversed, iterator, memo, context);
|
118
115
|
};
|
119
116
|
|
120
|
-
// Return the first value which passes a truth test.
|
121
|
-
_.detect = function(obj, iterator, context) {
|
117
|
+
// Return the first value which passes a truth test. Aliased as `detect`.
|
118
|
+
_.find = _.detect = function(obj, iterator, context) {
|
122
119
|
var result;
|
123
120
|
each(obj, function(value, index, list) {
|
124
121
|
if (iterator.call(context, value, index, list)) {
|
@@ -131,7 +128,8 @@
|
|
131
128
|
|
132
129
|
// Return all the elements that pass a truth test.
|
133
130
|
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
134
|
-
|
131
|
+
// Aliased as `select`.
|
132
|
+
_.filter = _.select = function(obj, iterator, context) {
|
135
133
|
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
|
136
134
|
var results = [];
|
137
135
|
each(obj, function(value, index, list) {
|
@@ -151,7 +149,8 @@
|
|
151
149
|
|
152
150
|
// Determine whether all of the elements match a truth test.
|
153
151
|
// Delegates to **ECMAScript 5**'s native `every` if available.
|
154
|
-
|
152
|
+
// Aliased as `all`.
|
153
|
+
_.every = _.all = function(obj, iterator, context) {
|
155
154
|
iterator = iterator || _.identity;
|
156
155
|
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
|
157
156
|
var result = true;
|
@@ -163,7 +162,8 @@
|
|
163
162
|
|
164
163
|
// Determine if at least one element in the object matches a truth test.
|
165
164
|
// Delegates to **ECMAScript 5**'s native `some` if available.
|
166
|
-
|
165
|
+
// Aliased as `any`.
|
166
|
+
_.some = _.any = function(obj, iterator, context) {
|
167
167
|
iterator = iterator || _.identity;
|
168
168
|
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
169
169
|
var result = false;
|
@@ -174,7 +174,8 @@
|
|
174
174
|
};
|
175
175
|
|
176
176
|
// Determine if a given value is included in the array or object using `===`.
|
177
|
-
|
177
|
+
// Aliased as `contains`.
|
178
|
+
_.include = _.contains = function(obj, target) {
|
178
179
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
179
180
|
var found = false;
|
180
181
|
each(obj, function(value) {
|
@@ -263,7 +264,7 @@
|
|
263
264
|
// Get the first element of an array. Passing **n** will return the first N
|
264
265
|
// values in the array. Aliased as `head`. The **guard** check allows it to work
|
265
266
|
// with `_.map`.
|
266
|
-
_.first = function(array, n, guard) {
|
267
|
+
_.first = _.head = function(array, n, guard) {
|
267
268
|
return n && !guard ? slice.call(array, 0, n) : array[0];
|
268
269
|
};
|
269
270
|
|
@@ -271,7 +272,7 @@
|
|
271
272
|
// Especially useful on the arguments object. Passing an **index** will return
|
272
273
|
// the rest of the values in the array from that index onward. The **guard**
|
273
274
|
// check allows it to work with `_.map`.
|
274
|
-
_.rest = function(array, index, guard) {
|
275
|
+
_.rest = _.tail = function(array, index, guard) {
|
275
276
|
return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
|
276
277
|
};
|
277
278
|
|
@@ -302,7 +303,8 @@
|
|
302
303
|
|
303
304
|
// Produce a duplicate-free version of the array. If the array has already
|
304
305
|
// been sorted, you have the option of using a faster algorithm.
|
305
|
-
|
306
|
+
// Aliased as `unique`.
|
307
|
+
_.uniq = _.unique = function(array, isSorted) {
|
306
308
|
return _.reduce(array, function(memo, el, i) {
|
307
309
|
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
|
308
310
|
return memo;
|
@@ -330,7 +332,7 @@
|
|
330
332
|
return results;
|
331
333
|
};
|
332
334
|
|
333
|
-
// If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
|
335
|
+
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
334
336
|
// we need this function. Return the position of the first occurence of an
|
335
337
|
// item in an array, or -1 if the item is not included in the array.
|
336
338
|
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
@@ -353,19 +355,22 @@
|
|
353
355
|
// the native Python `range()` function. See
|
354
356
|
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
355
357
|
_.range = function(start, stop, step) {
|
356
|
-
var
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
358
|
+
var args = slice.call(arguments),
|
359
|
+
solo = args.length <= 1,
|
360
|
+
start = solo ? 0 : args[0],
|
361
|
+
stop = solo ? args[0] : args[1],
|
362
|
+
step = args[2] || 1,
|
363
|
+
len = Math.max(Math.ceil((stop - start) / step), 0),
|
364
|
+
idx = 0,
|
365
|
+
range = new Array(len);
|
366
|
+
while (idx < len) {
|
367
|
+
range[idx++] = start;
|
368
|
+
start += step;
|
365
369
|
}
|
370
|
+
return range;
|
366
371
|
};
|
367
372
|
|
368
|
-
// Function Functions
|
373
|
+
// Function (ahem) Functions
|
369
374
|
// ------------------
|
370
375
|
|
371
376
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
@@ -450,7 +455,8 @@
|
|
450
455
|
};
|
451
456
|
|
452
457
|
// Return a sorted list of the function names available on the object.
|
453
|
-
|
458
|
+
// Aliased as `methods`
|
459
|
+
_.functions = _.methods = function(obj) {
|
454
460
|
return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
|
455
461
|
};
|
456
462
|
|
@@ -464,8 +470,7 @@
|
|
464
470
|
|
465
471
|
// Create a (shallow-cloned) duplicate of an object.
|
466
472
|
_.clone = function(obj) {
|
467
|
-
|
468
|
-
return _.extend({}, obj);
|
473
|
+
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
469
474
|
};
|
470
475
|
|
471
476
|
// Invokes interceptor with the obj, and then returns obj.
|
@@ -652,20 +657,6 @@
|
|
652
657
|
return data ? func(data) : func;
|
653
658
|
};
|
654
659
|
|
655
|
-
// Aliases:
|
656
|
-
// --------
|
657
|
-
|
658
|
-
_.each = _.forEach;
|
659
|
-
_.foldl = _.inject = _.reduce;
|
660
|
-
_.foldr = _.reduceRight;
|
661
|
-
_.select = _.filter;
|
662
|
-
_.all = _.every;
|
663
|
-
_.any = _.some;
|
664
|
-
_.contains = _.include;
|
665
|
-
_.head = _.first;
|
666
|
-
_.tail = _.rest;
|
667
|
-
_.methods = _.functions;
|
668
|
-
|
669
660
|
// The OOP Wrapper
|
670
661
|
// ---------------
|
671
662
|
|
@@ -674,6 +665,9 @@
|
|
674
665
|
// underscore functions. Wrapped objects may be chained.
|
675
666
|
var wrapper = function(obj) { this._wrapped = obj; };
|
676
667
|
|
668
|
+
// Expose `wrapper.prototype` as `_.prototype`
|
669
|
+
_.prototype = wrapper.prototype;
|
670
|
+
|
677
671
|
// Helper function to continue chaining intermediate results.
|
678
672
|
var result = function(obj, chain) {
|
679
673
|
return chain ? _(obj).chain() : obj;
|