underscore-source 0.2.0 → 0.3.0
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.
@@ -2,19 +2,31 @@
|
|
2
2
|
// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
|
3
3
|
// Underscore is freely distributable under the terms of the MIT license.
|
4
4
|
// Portions of Underscore are inspired by or borrowed from Prototype.js,
|
5
|
-
// Oliver Steele's Functional,
|
5
|
+
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
6
6
|
// For all details and documentation:
|
7
7
|
// http://documentcloud.github.com/underscore/
|
8
8
|
|
9
9
|
(function() {
|
10
10
|
|
11
|
-
|
11
|
+
/*------------------------- Baseline setup ---------------------------------*/
|
12
12
|
|
13
|
-
|
13
|
+
// Are we running in CommonJS or in the browser?
|
14
|
+
var commonJS = (typeof window === 'undefined' && typeof exports !== 'undefined');
|
14
15
|
|
15
|
-
|
16
|
+
// Save the previous value of the "_" variable.
|
17
|
+
var previousUnderscore = commonJS ? null : window._;
|
16
18
|
|
17
|
-
|
19
|
+
// Keep the identity function around for default iterators.
|
20
|
+
var identity = function(value) { return value; };
|
21
|
+
|
22
|
+
// Create a safe reference to the Underscore object for the functions below.
|
23
|
+
var _ = {};
|
24
|
+
|
25
|
+
// Export the Underscore object for CommonJS, assign it globally otherwise.
|
26
|
+
commonJS ? _ = exports : window._ = _;
|
27
|
+
|
28
|
+
// Current version.
|
29
|
+
_.VERSION = '0.3.0';
|
18
30
|
|
19
31
|
/*------------------------ Collection Functions: ---------------------------*/
|
20
32
|
|
@@ -26,12 +38,12 @@
|
|
26
38
|
if (obj.forEach) {
|
27
39
|
obj.forEach(iterator, context);
|
28
40
|
} else if (obj.length) {
|
29
|
-
for (var i=0
|
41
|
+
for (var i=0, l = obj.length; i<l; i++) iterator.call(context, obj[i], i);
|
30
42
|
} else if (obj.each) {
|
31
43
|
obj.each(function(value) { iterator.call(context, value, index++); });
|
32
44
|
} else {
|
33
45
|
var i = 0;
|
34
|
-
for (var key in obj) {
|
46
|
+
for (var key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
35
47
|
var value = obj[key], pair = [key, value];
|
36
48
|
pair.key = key;
|
37
49
|
pair.value = value;
|
@@ -44,7 +56,7 @@
|
|
44
56
|
return obj;
|
45
57
|
};
|
46
58
|
|
47
|
-
// Return the results of applying the iterator to each element. Use
|
59
|
+
// Return the results of applying the iterator to each element. Use JavaScript
|
48
60
|
// 1.6's version of map, if possible.
|
49
61
|
_.map = function(obj, iterator, context) {
|
50
62
|
if (obj && obj.map) return obj.map(iterator, context);
|
@@ -76,13 +88,13 @@
|
|
76
88
|
return result;
|
77
89
|
};
|
78
90
|
|
79
|
-
// Return all the elements that pass a truth test. Use
|
91
|
+
// Return all the elements that pass a truth test. Use JavaScript 1.6's
|
80
92
|
// filter(), if it exists.
|
81
93
|
_.select = function(obj, iterator, context) {
|
82
94
|
if (obj.filter) return obj.filter(iterator, context);
|
83
95
|
var results = [];
|
84
96
|
_.each(obj, function(value, index) {
|
85
|
-
|
97
|
+
iterator.call(context, value, index) && results.push(value);
|
86
98
|
});
|
87
99
|
return results;
|
88
100
|
};
|
@@ -91,32 +103,31 @@
|
|
91
103
|
_.reject = function(obj, iterator, context) {
|
92
104
|
var results = [];
|
93
105
|
_.each(obj, function(value, index) {
|
94
|
-
|
106
|
+
!iterator.call(context, value, index) && results.push(value);
|
95
107
|
});
|
96
108
|
return results;
|
97
109
|
};
|
98
110
|
|
99
111
|
// Determine whether all of the elements match a truth test. Delegate to
|
100
|
-
//
|
112
|
+
// JavaScript 1.6's every(), if it is present.
|
101
113
|
_.all = function(obj, iterator, context) {
|
102
|
-
iterator = iterator ||
|
114
|
+
iterator = iterator || identity;
|
103
115
|
if (obj.every) return obj.every(iterator, context);
|
104
116
|
var result = true;
|
105
117
|
_.each(obj, function(value, index) {
|
106
|
-
result = result &&
|
107
|
-
if (!result) throw '__break__';
|
118
|
+
if (!(result = result && iterator.call(context, value, index))) throw '__break__';
|
108
119
|
});
|
109
120
|
return result;
|
110
121
|
};
|
111
122
|
|
112
123
|
// Determine if at least one element in the object matches a truth test. Use
|
113
|
-
//
|
124
|
+
// JavaScript 1.6's some(), if it exists.
|
114
125
|
_.any = function(obj, iterator, context) {
|
115
|
-
iterator = iterator ||
|
126
|
+
iterator = iterator || identity;
|
116
127
|
if (obj.some) return obj.some(iterator, context);
|
117
128
|
var result = false;
|
118
129
|
_.each(obj, function(value, index) {
|
119
|
-
if (result =
|
130
|
+
if (result = iterator.call(context, value, index)) throw '__break__';
|
120
131
|
});
|
121
132
|
return result;
|
122
133
|
};
|
@@ -127,8 +138,7 @@
|
|
127
138
|
if (_.isArray(obj)) return _.indexOf(obj, target) != -1;
|
128
139
|
var found = false;
|
129
140
|
_.each(obj, function(pair) {
|
130
|
-
if (pair.value === target) {
|
131
|
-
found = true;
|
141
|
+
if (found = pair.value === target) {
|
132
142
|
throw '__break__';
|
133
143
|
}
|
134
144
|
});
|
@@ -153,10 +163,10 @@
|
|
153
163
|
// Return the maximum item or (item-based computation).
|
154
164
|
_.max = function(obj, iterator, context) {
|
155
165
|
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
|
156
|
-
var result;
|
166
|
+
var result = {computed : -Infinity};
|
157
167
|
_.each(obj, function(value, index) {
|
158
168
|
var computed = iterator ? iterator.call(context, value, index) : value;
|
159
|
-
|
169
|
+
computed >= result.computed && (result = {value : value, computed : computed});
|
160
170
|
});
|
161
171
|
return result.value;
|
162
172
|
};
|
@@ -164,10 +174,10 @@
|
|
164
174
|
// Return the minimum element (or element-based computation).
|
165
175
|
_.min = function(obj, iterator, context) {
|
166
176
|
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
|
167
|
-
var result;
|
177
|
+
var result = {computed : Infinity};
|
168
178
|
_.each(obj, function(value, index) {
|
169
179
|
var computed = iterator ? iterator.call(context, value, index) : value;
|
170
|
-
|
180
|
+
computed < result.computed && (result = {value : value, computed : computed});
|
171
181
|
});
|
172
182
|
return result.value;
|
173
183
|
};
|
@@ -188,7 +198,7 @@
|
|
188
198
|
// Use a comparator function to figure out at what index an object should
|
189
199
|
// be inserted so as to maintain order. Uses binary search.
|
190
200
|
_.sortedIndex = function(array, obj, iterator) {
|
191
|
-
iterator = iterator ||
|
201
|
+
iterator = iterator || identity;
|
192
202
|
var low = 0, high = array.length;
|
193
203
|
while (low < high) {
|
194
204
|
var mid = (low + high) >> 1;
|
@@ -276,15 +286,16 @@
|
|
276
286
|
// item in an array, or -1 if the item is not included in the array.
|
277
287
|
_.indexOf = function(array, item) {
|
278
288
|
if (array.indexOf) return array.indexOf(item);
|
279
|
-
for (i=0
|
289
|
+
for (i=0, l=array.length; i<l; i++) if (array[i] === item) return i;
|
280
290
|
return -1;
|
281
291
|
};
|
282
292
|
|
283
|
-
// Provide
|
293
|
+
// Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
|
284
294
|
// if possible.
|
285
295
|
_.lastIndexOf = function(array, item) {
|
286
296
|
if (array.lastIndexOf) return array.lastIndexOf(item);
|
287
|
-
|
297
|
+
var i = array.length;
|
298
|
+
while (i--) if (array[i] === item) return i;
|
288
299
|
return -1;
|
289
300
|
};
|
290
301
|
|
@@ -403,7 +414,7 @@
|
|
403
414
|
|
404
415
|
// Is a given value a Function?
|
405
416
|
_.isFunction = function(obj) {
|
406
|
-
return
|
417
|
+
return Object.prototype.toString.call(obj) == '[object Function]';
|
407
418
|
};
|
408
419
|
|
409
420
|
// Is a given variable undefined?
|
@@ -416,7 +427,7 @@
|
|
416
427
|
// Run Underscore.js in noConflict mode, returning the '_' variable to its
|
417
428
|
// previous owner. Returns a reference to the Underscore object.
|
418
429
|
_.noConflict = function() {
|
419
|
-
|
430
|
+
if (!commonJS) window._ = previousUnderscore;
|
420
431
|
return this;
|
421
432
|
};
|
422
433
|
|
@@ -427,8 +438,8 @@
|
|
427
438
|
return prefix ? prefix + id : id;
|
428
439
|
};
|
429
440
|
|
430
|
-
//
|
431
|
-
// "Secrets of the
|
441
|
+
// JavaScript templating a-la ERB, pilfered from John Resig's
|
442
|
+
// "Secrets of the JavaScript Ninja", page 83.
|
432
443
|
_.template = function(str, data) {
|
433
444
|
var fn = new Function('obj',
|
434
445
|
'var p=[],print=function(){p.push.apply(p,arguments);};' +
|
@@ -451,10 +462,6 @@
|
|
451
462
|
_.inject = _.reduce;
|
452
463
|
_.filter = _.select;
|
453
464
|
_.every = _.all;
|
454
|
-
_.some = _.any;
|
455
|
-
|
456
|
-
/*------------------------- Export for ServerJS ----------------------------*/
|
457
|
-
|
458
|
-
if (!_.isUndefined(exports)) exports = _;
|
465
|
+
_.some = _.any;
|
459
466
|
|
460
467
|
})();
|