underscore-source 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,4 @@
|
|
1
|
+
// Underscore.js 1.1.3
|
1
2
|
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
|
2
3
|
// Underscore is freely distributable under the MIT license.
|
3
4
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
@@ -16,18 +17,17 @@
|
|
16
17
|
// Save the previous value of the `_` variable.
|
17
18
|
var previousUnderscore = root._;
|
18
19
|
|
19
|
-
// Establish the object that gets
|
20
|
-
var breaker =
|
20
|
+
// Establish the object that gets returned to break out of a loop iteration.
|
21
|
+
var breaker = {};
|
21
22
|
|
22
23
|
// Save bytes in the minified (but not gzipped) version:
|
23
24
|
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
|
24
25
|
|
25
26
|
// Create quick reference variables for speed access to core prototypes.
|
26
|
-
var slice
|
27
|
-
unshift
|
28
|
-
toString
|
29
|
-
hasOwnProperty
|
30
|
-
propertyIsEnumerable = ObjProto.propertyIsEnumerable;
|
27
|
+
var slice = ArrayProto.slice,
|
28
|
+
unshift = ArrayProto.unshift,
|
29
|
+
toString = ObjProto.toString,
|
30
|
+
hasOwnProperty = ObjProto.hasOwnProperty;
|
31
31
|
|
32
32
|
// All **ECMAScript 5** native function implementations that we hope to use
|
33
33
|
// are declared here.
|
@@ -47,14 +47,18 @@
|
|
47
47
|
// Create a safe reference to the Underscore object for use below.
|
48
48
|
var _ = function(obj) { return new wrapper(obj); };
|
49
49
|
|
50
|
-
// Export the Underscore object for **CommonJS
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
// Export the Underscore object for **CommonJS**, with backwards-compatibility
|
51
|
+
// for the old `require()` API. If we're not in CommonJS, add `_` to the
|
52
|
+
// global object.
|
53
|
+
if (typeof module !== 'undefined' && module.exports) {
|
54
|
+
module.exports = _;
|
55
|
+
_._ = _;
|
56
|
+
} else {
|
57
|
+
root._ = _;
|
58
|
+
}
|
55
59
|
|
56
60
|
// Current version.
|
57
|
-
_.VERSION = '1.1.
|
61
|
+
_.VERSION = '1.1.3';
|
58
62
|
|
59
63
|
// Collection Functions
|
60
64
|
// --------------------
|
@@ -63,20 +67,20 @@
|
|
63
67
|
// Handles objects implementing `forEach`, arrays, and raw objects.
|
64
68
|
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
65
69
|
var each = _.each = _.forEach = function(obj, iterator, context) {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
var value;
|
71
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
72
|
+
obj.forEach(iterator, context);
|
73
|
+
} else if (_.isNumber(obj.length)) {
|
74
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
75
|
+
if (iterator.call(context, obj[i], i, obj) === breaker) return;
|
76
|
+
}
|
77
|
+
} else {
|
78
|
+
for (var key in obj) {
|
79
|
+
if (hasOwnProperty.call(obj, key)) {
|
80
|
+
if (iterator.call(context, obj[key], key, obj) === breaker) return;
|
74
81
|
}
|
75
82
|
}
|
76
|
-
} catch(e) {
|
77
|
-
if (e != breaker) throw e;
|
78
83
|
}
|
79
|
-
return obj;
|
80
84
|
};
|
81
85
|
|
82
86
|
// Return the results of applying the iterator to each element.
|
@@ -93,12 +97,17 @@
|
|
93
97
|
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
94
98
|
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
95
99
|
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
100
|
+
var initial = memo !== void 0;
|
96
101
|
if (nativeReduce && obj.reduce === nativeReduce) {
|
97
102
|
if (context) iterator = _.bind(iterator, context);
|
98
|
-
return obj.reduce(iterator, memo);
|
103
|
+
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
|
99
104
|
}
|
100
105
|
each(obj, function(value, index, list) {
|
101
|
-
|
106
|
+
if (!initial && index === 0) {
|
107
|
+
memo = value;
|
108
|
+
} else {
|
109
|
+
memo = iterator.call(context, memo, value, index, list);
|
110
|
+
}
|
102
111
|
});
|
103
112
|
return memo;
|
104
113
|
};
|
@@ -108,7 +117,7 @@
|
|
108
117
|
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
109
118
|
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
110
119
|
if (context) iterator = _.bind(iterator, context);
|
111
|
-
return obj.reduceRight(iterator, memo);
|
120
|
+
return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
112
121
|
}
|
113
122
|
var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
|
114
123
|
return _.reduce(reversed, iterator, memo, context);
|
@@ -117,10 +126,10 @@
|
|
117
126
|
// Return the first value which passes a truth test. Aliased as `detect`.
|
118
127
|
_.find = _.detect = function(obj, iterator, context) {
|
119
128
|
var result;
|
120
|
-
|
129
|
+
any(obj, function(value, index, list) {
|
121
130
|
if (iterator.call(context, value, index, list)) {
|
122
131
|
result = value;
|
123
|
-
|
132
|
+
return true;
|
124
133
|
}
|
125
134
|
});
|
126
135
|
return result;
|
@@ -155,7 +164,7 @@
|
|
155
164
|
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
|
156
165
|
var result = true;
|
157
166
|
each(obj, function(value, index, list) {
|
158
|
-
if (!(result = result && iterator.call(context, value, index, list)))
|
167
|
+
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
|
159
168
|
});
|
160
169
|
return result;
|
161
170
|
};
|
@@ -163,12 +172,12 @@
|
|
163
172
|
// Determine if at least one element in the object matches a truth test.
|
164
173
|
// Delegates to **ECMAScript 5**'s native `some` if available.
|
165
174
|
// Aliased as `any`.
|
166
|
-
_.some = _.any = function(obj, iterator, context) {
|
175
|
+
var any = _.some = _.any = function(obj, iterator, context) {
|
167
176
|
iterator = iterator || _.identity;
|
168
177
|
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
169
178
|
var result = false;
|
170
179
|
each(obj, function(value, index, list) {
|
171
|
-
if (result = iterator.call(context, value, index, list))
|
180
|
+
if (result = iterator.call(context, value, index, list)) return breaker;
|
172
181
|
});
|
173
182
|
return result;
|
174
183
|
};
|
@@ -178,8 +187,8 @@
|
|
178
187
|
_.include = _.contains = function(obj, target) {
|
179
188
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
180
189
|
var found = false;
|
181
|
-
|
182
|
-
if (found = value === target)
|
190
|
+
any(obj, function(value) {
|
191
|
+
if (found = value === target) return true;
|
183
192
|
});
|
184
193
|
return found;
|
185
194
|
};
|
@@ -333,7 +342,7 @@
|
|
333
342
|
};
|
334
343
|
|
335
344
|
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
336
|
-
// we need this function. Return the position of the first
|
345
|
+
// we need this function. Return the position of the first occurrence of an
|
337
346
|
// item in an array, or -1 if the item is not included in the array.
|
338
347
|
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
339
348
|
_.indexOf = function(array, item) {
|
@@ -414,6 +423,33 @@
|
|
414
423
|
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
415
424
|
};
|
416
425
|
|
426
|
+
// Internal function used to implement `_.throttle` and `_.debounce`.
|
427
|
+
var limit = function(func, wait, debounce) {
|
428
|
+
var timeout;
|
429
|
+
return function() {
|
430
|
+
var context = this, args = arguments;
|
431
|
+
var throttler = function() {
|
432
|
+
timeout = null;
|
433
|
+
func.apply(context, args);
|
434
|
+
};
|
435
|
+
if (debounce) clearTimeout(timeout);
|
436
|
+
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
437
|
+
};
|
438
|
+
};
|
439
|
+
|
440
|
+
// Returns a function, that, when invoked, will only be triggered at most once
|
441
|
+
// during a given window of time.
|
442
|
+
_.throttle = function(func, wait) {
|
443
|
+
return limit(func, wait, false);
|
444
|
+
};
|
445
|
+
|
446
|
+
// Returns a function, that, as long as it continues to be invoked, will not
|
447
|
+
// be triggered. The function will be called after it stops being called for
|
448
|
+
// N milliseconds.
|
449
|
+
_.debounce = function(func, wait) {
|
450
|
+
return limit(func, wait, true);
|
451
|
+
};
|
452
|
+
|
417
453
|
// Returns the first function passed as an argument to the second,
|
418
454
|
// allowing you to adjust arguments, run code before and after, and
|
419
455
|
// conditionally execute the original function.
|
@@ -552,7 +588,13 @@
|
|
552
588
|
|
553
589
|
// Is a given value a number?
|
554
590
|
_.isNumber = function(obj) {
|
555
|
-
return (obj ===
|
591
|
+
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
|
592
|
+
};
|
593
|
+
|
594
|
+
// Is the given value NaN -- this one is interesting. NaN != NaN, and
|
595
|
+
// isNaN(undefined) == true, so we make sure it's a number first.
|
596
|
+
_.isNaN = function(obj) {
|
597
|
+
return toString.call(obj) === '[object Number]' && isNaN(obj);
|
556
598
|
};
|
557
599
|
|
558
600
|
// Is a given value a boolean?
|
@@ -570,12 +612,6 @@
|
|
570
612
|
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
|
571
613
|
};
|
572
614
|
|
573
|
-
// Is the given value NaN -- this one is interesting. NaN != NaN, and
|
574
|
-
// isNaN(undefined) == true, so we make sure it's a number first.
|
575
|
-
_.isNaN = function(obj) {
|
576
|
-
return _.isNumber(obj) && isNaN(obj);
|
577
|
-
};
|
578
|
-
|
579
615
|
// Is a given value equal to null?
|
580
616
|
_.isNull = function(obj) {
|
581
617
|
return obj === null;
|
@@ -583,7 +619,7 @@
|
|
583
619
|
|
584
620
|
// Is a given variable undefined?
|
585
621
|
_.isUndefined = function(obj) {
|
586
|
-
return
|
622
|
+
return obj === void 0;
|
587
623
|
};
|
588
624
|
|
589
625
|
// Utility Functions
|
@@ -606,11 +642,6 @@
|
|
606
642
|
for (var i = 0; i < n; i++) iterator.call(context, i);
|
607
643
|
};
|
608
644
|
|
609
|
-
// Break out of the middle of an iteration.
|
610
|
-
_.breakLoop = function() {
|
611
|
-
throw breaker;
|
612
|
-
};
|
613
|
-
|
614
645
|
// Add your own custom functions to the Underscore object, ensuring that
|
615
646
|
// they're correctly added to the OOP wrapper as well.
|
616
647
|
_.mixin = function(obj) {
|
@@ -641,7 +672,8 @@
|
|
641
672
|
var c = _.templateSettings;
|
642
673
|
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
643
674
|
'with(obj||{}){__p.push(\'' +
|
644
|
-
str.replace(
|
675
|
+
str.replace(/\\/g, '\\\\')
|
676
|
+
.replace(/'/g, "\\'")
|
645
677
|
.replace(c.interpolate, function(match, code) {
|
646
678
|
return "'," + code.replace(/\\'/g, "'") + ",'";
|
647
679
|
})
|