underscore-source 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,8 +30,15 @@
|
|
30
30
|
// Export the Underscore object for CommonJS.
|
31
31
|
if (typeof exports !== 'undefined') exports._ = _;
|
32
32
|
|
33
|
+
// Create quick reference variables for speed access to core prototypes.
|
34
|
+
var slice = Array.prototype.slice,
|
35
|
+
unshift = Array.prototype.unshift,
|
36
|
+
toString = Object.prototype.toString,
|
37
|
+
hasOwnProperty = Object.prototype.hasOwnProperty,
|
38
|
+
propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
39
|
+
|
33
40
|
// Current version.
|
34
|
-
_.VERSION = '0.5.
|
41
|
+
_.VERSION = '0.5.1';
|
35
42
|
|
36
43
|
/*------------------------ Collection Functions: ---------------------------*/
|
37
44
|
|
@@ -42,7 +49,7 @@
|
|
42
49
|
try {
|
43
50
|
if (obj.forEach) {
|
44
51
|
obj.forEach(iterator, context);
|
45
|
-
} else if (obj.
|
52
|
+
} else if (_.isArray(obj) || _.isArguments(obj)) {
|
46
53
|
for (var i=0, l=obj.length; i<l; i++) iterator.call(context, obj[i], i, obj);
|
47
54
|
} else {
|
48
55
|
var keys = _.keys(obj), l = keys.length;
|
@@ -57,7 +64,7 @@
|
|
57
64
|
// Return the results of applying the iterator to each element. Use JavaScript
|
58
65
|
// 1.6's version of map, if possible.
|
59
66
|
_.map = function(obj, iterator, context) {
|
60
|
-
if (obj && obj.map) return obj.map(iterator, context);
|
67
|
+
if (obj && _.isFunction(obj.map)) return obj.map(iterator, context);
|
61
68
|
var results = [];
|
62
69
|
_.each(obj, function(value, index, list) {
|
63
70
|
results.push(iterator.call(context, value, index, list));
|
@@ -68,7 +75,7 @@
|
|
68
75
|
// Reduce builds up a single result from a list of values. Also known as
|
69
76
|
// inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
|
70
77
|
_.reduce = function(obj, memo, iterator, context) {
|
71
|
-
if (obj && obj.reduce) return obj.reduce(_.bind(iterator, context), memo);
|
78
|
+
if (obj && _.isFunction(obj.reduce)) return obj.reduce(_.bind(iterator, context), memo);
|
72
79
|
_.each(obj, function(value, index, list) {
|
73
80
|
memo = iterator.call(context, memo, value, index, list);
|
74
81
|
});
|
@@ -78,7 +85,7 @@
|
|
78
85
|
// The right-associative version of reduce, also known as foldr. Uses
|
79
86
|
// JavaScript 1.8's version of reduceRight, if available.
|
80
87
|
_.reduceRight = function(obj, memo, iterator, context) {
|
81
|
-
if (obj && obj.reduceRight) return obj.reduceRight(_.bind(iterator, context), memo);
|
88
|
+
if (obj && _.isFunction(obj.reduceRight)) return obj.reduceRight(_.bind(iterator, context), memo);
|
82
89
|
var reversed = _.clone(_.toArray(obj)).reverse();
|
83
90
|
_.each(reversed, function(value, index) {
|
84
91
|
memo = iterator.call(context, memo, value, index, obj);
|
@@ -101,7 +108,7 @@
|
|
101
108
|
// Return all the elements that pass a truth test. Use JavaScript 1.6's
|
102
109
|
// filter(), if it exists.
|
103
110
|
_.select = function(obj, iterator, context) {
|
104
|
-
if (obj.filter) return obj.filter(iterator, context);
|
111
|
+
if (obj && _.isFunction(obj.filter)) return obj.filter(iterator, context);
|
105
112
|
var results = [];
|
106
113
|
_.each(obj, function(value, index, list) {
|
107
114
|
iterator.call(context, value, index, list) && results.push(value);
|
@@ -122,7 +129,7 @@
|
|
122
129
|
// JavaScript 1.6's every(), if it is present.
|
123
130
|
_.all = function(obj, iterator, context) {
|
124
131
|
iterator = iterator || _.identity;
|
125
|
-
if (obj.every) return obj.every(iterator, context);
|
132
|
+
if (obj && _.isFunction(obj.every)) return obj.every(iterator, context);
|
126
133
|
var result = true;
|
127
134
|
_.each(obj, function(value, index, list) {
|
128
135
|
if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop();
|
@@ -134,7 +141,7 @@
|
|
134
141
|
// JavaScript 1.6's some(), if it exists.
|
135
142
|
_.any = function(obj, iterator, context) {
|
136
143
|
iterator = iterator || _.identity;
|
137
|
-
if (obj.some) return obj.some(iterator, context);
|
144
|
+
if (obj && _.isFunction(obj.some)) return obj.some(iterator, context);
|
138
145
|
var result = false;
|
139
146
|
_.each(obj, function(value, index, list) {
|
140
147
|
if (result = iterator.call(context, value, index, list)) _.breakLoop();
|
@@ -215,9 +222,10 @@
|
|
215
222
|
|
216
223
|
// Convert anything iterable into a real, live array.
|
217
224
|
_.toArray = function(iterable) {
|
218
|
-
if (!iterable)
|
219
|
-
if (iterable.toArray)
|
220
|
-
if (_.isArray(iterable))
|
225
|
+
if (!iterable) return [];
|
226
|
+
if (iterable.toArray) return iterable.toArray();
|
227
|
+
if (_.isArray(iterable)) return iterable;
|
228
|
+
if (_.isArguments(iterable)) return slice.call(iterable);
|
221
229
|
return _.map(iterable, function(val){ return val; });
|
222
230
|
};
|
223
231
|
|
@@ -229,16 +237,18 @@
|
|
229
237
|
/*-------------------------- Array Functions: ------------------------------*/
|
230
238
|
|
231
239
|
// Get the first element of an array. Passing "n" will return the first N
|
232
|
-
// values in the array. Aliased as "head".
|
233
|
-
_.
|
234
|
-
|
240
|
+
// values in the array. Aliased as "head". The "guard" check allows it to work
|
241
|
+
// with _.map.
|
242
|
+
_.first = function(array, n, guard) {
|
243
|
+
return n && !guard ? slice.call(array, 0, n) : array[0];
|
235
244
|
};
|
236
245
|
|
237
246
|
// Returns everything but the first entry of the array. Aliased as "tail".
|
238
247
|
// Especially useful on the arguments object. Passing an "index" will return
|
239
|
-
// the rest of the values in the array from that index onward.
|
240
|
-
|
241
|
-
|
248
|
+
// the rest of the values in the array from that index onward. The "guard"
|
249
|
+
//check allows it to work with _.map.
|
250
|
+
_.rest = function(array, index, guard) {
|
251
|
+
return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
|
242
252
|
};
|
243
253
|
|
244
254
|
// Get the last element of an array.
|
@@ -270,7 +280,7 @@
|
|
270
280
|
// been sorted, you have the option of using a faster algorithm.
|
271
281
|
_.uniq = function(array, isSorted) {
|
272
282
|
return _.reduce(array, [], function(memo, el, i) {
|
273
|
-
if (0 == i || (isSorted ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
|
283
|
+
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
|
274
284
|
return memo;
|
275
285
|
});
|
276
286
|
};
|
@@ -392,7 +402,7 @@
|
|
392
402
|
_.keys = function(obj) {
|
393
403
|
if(_.isArray(obj)) return _.range(0, obj.length);
|
394
404
|
var keys = [];
|
395
|
-
for (var key in obj) if (
|
405
|
+
for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
|
396
406
|
return keys;
|
397
407
|
};
|
398
408
|
|
@@ -401,6 +411,11 @@
|
|
401
411
|
return _.map(obj, _.identity);
|
402
412
|
};
|
403
413
|
|
414
|
+
// Return a sorted list of the function names available in Underscore.
|
415
|
+
_.functions = function(obj) {
|
416
|
+
return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
|
417
|
+
};
|
418
|
+
|
404
419
|
// Extend a given object with all of the properties in a source object.
|
405
420
|
_.extend = function(destination, source) {
|
406
421
|
for (var property in source) destination[property] = source[property];
|
@@ -422,6 +437,8 @@
|
|
422
437
|
if (atype != btype) return false;
|
423
438
|
// Basic equality test (watch out for coercions).
|
424
439
|
if (a == b) return true;
|
440
|
+
// One is falsy and the other truthy.
|
441
|
+
if ((!a && b) || (a && !b)) return false;
|
425
442
|
// One of them implements an isEqual()?
|
426
443
|
if (a.isEqual) return a.isEqual(b);
|
427
444
|
// Check dates' integer values.
|
@@ -457,6 +474,11 @@
|
|
457
474
|
return !!(obj && obj.nodeType == 1);
|
458
475
|
};
|
459
476
|
|
477
|
+
// Is a given variable an arguments object?
|
478
|
+
_.isArguments = function(obj) {
|
479
|
+
return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length');
|
480
|
+
};
|
481
|
+
|
460
482
|
// Is the given value NaN -- this one is interesting. NaN != NaN, and
|
461
483
|
// isNaN(undefined) == true, so we make sure it's a number first.
|
462
484
|
_.isNaN = function(obj) {
|
@@ -473,13 +495,15 @@
|
|
473
495
|
return typeof obj == 'undefined';
|
474
496
|
};
|
475
497
|
|
476
|
-
// Define the isArray, isDate, isFunction, isNumber, isRegExp, and
|
477
|
-
//
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
498
|
+
// Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString
|
499
|
+
// functions based on their toString identifiers.
|
500
|
+
var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'];
|
501
|
+
for (var i=0, l=types.length; i<l; i++) {
|
502
|
+
(function() {
|
503
|
+
var identifier = '[object ' + types[i] + ']';
|
504
|
+
_['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; };
|
505
|
+
})();
|
506
|
+
}
|
483
507
|
|
484
508
|
/* -------------------------- Utility Functions: -------------------------- */
|
485
509
|
|
@@ -508,11 +532,6 @@
|
|
508
532
|
return prefix ? prefix + id : id;
|
509
533
|
};
|
510
534
|
|
511
|
-
// Return a sorted list of the function names available in Underscore.
|
512
|
-
_.functions = function(obj) {
|
513
|
-
return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
|
514
|
-
};
|
515
|
-
|
516
535
|
// JavaScript templating a-la ERB, pilfered from John Resig's
|
517
536
|
// "Secrets of the JavaScript Ninja", page 83.
|
518
537
|
_.template = function(str, data) {
|
@@ -552,24 +571,27 @@
|
|
552
571
|
|
553
572
|
// Add all of the Underscore functions to the wrapper object.
|
554
573
|
_.each(_.functions(_), function(name) {
|
574
|
+
var method = _[name];
|
555
575
|
wrapper.prototype[name] = function() {
|
556
|
-
|
557
|
-
return result(
|
576
|
+
unshift.call(arguments, this._wrapped);
|
577
|
+
return result(method.apply(_, arguments), this._chain);
|
558
578
|
};
|
559
579
|
});
|
560
580
|
|
561
581
|
// Add all mutator Array functions to the wrapper.
|
562
582
|
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
583
|
+
var method = Array.prototype[name];
|
563
584
|
wrapper.prototype[name] = function() {
|
564
|
-
|
585
|
+
method.apply(this._wrapped, arguments);
|
565
586
|
return result(this._wrapped, this._chain);
|
566
587
|
};
|
567
588
|
});
|
568
589
|
|
569
590
|
// Add all accessor Array functions to the wrapper.
|
570
591
|
_.each(['concat', 'join', 'slice'], function(name) {
|
592
|
+
var method = Array.prototype[name];
|
571
593
|
wrapper.prototype[name] = function() {
|
572
|
-
return result(
|
594
|
+
return result(method.apply(this._wrapped, arguments), this._chain);
|
573
595
|
};
|
574
596
|
});
|
575
597
|
|