underscore.js (lodash-4.0.0) | : | underscore.js (lodash-4.17.21) | ||
---|---|---|---|---|
// Underscore.js 1.8.3 | // Underscore.js 1.8.3 | |||
// http://underscorejs.org | // http://underscorejs.org | |||
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | // (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | |||
// Underscore may be freely distributed under the MIT license. | // Underscore may be freely distributed under the MIT license. | |||
(function() { | (function() { | |||
// Baseline setup | // Baseline setup | |||
// -------------- | // -------------- | |||
// Establish the root object, `window` (`self`) in the browser, `global` | // Establish the root object, `window` (`self`) in the browser, `global` | |||
// on the server, or `this` in some virtual machines. We use `self` | // on the server, or `this` in some virtual machines. We use `self` | |||
// instead of `window` for `WebWorker` support. | // instead of `window` for `WebWorker` support. | |||
var root = typeof self == 'object' && self.self === self && self || | var root = typeof self == 'object' && self.self === self && self || | |||
typeof global == 'object' && global.global === global && global || | typeof global == 'object' && global.global === global && global || | |||
this; | this; | |||
// Save the previous value of the `_` variable. | // Save the previous value of the `_` variable. | |||
var previousUnderscore = root._; | var previousUnderscore = root._; | |||
// Save bytes in the minified (but not gzipped) version: | // Save bytes in the minified (but not gzipped) version: | |||
var ArrayProto = Array.prototype, ObjProto = Object.prototype; | var ArrayProto = Array.prototype, ObjProto = Object.prototype; | |||
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; | ||||
// Create quick reference variables for speed access to core prototypes. | // Create quick reference variables for speed access to core prototypes. | |||
var push = ArrayProto.push, | var push = ArrayProto.push, | |||
slice = ArrayProto.slice, | slice = ArrayProto.slice, | |||
toString = ObjProto.toString, | toString = ObjProto.toString, | |||
hasOwnProperty = ObjProto.hasOwnProperty; | hasOwnProperty = ObjProto.hasOwnProperty; | |||
// All **ECMAScript 5** native function implementations that we hope to use | // All **ECMAScript 5** native function implementations that we hope to use | |||
// are declared here. | // are declared here. | |||
var nativeIsArray = Array.isArray, | var nativeIsArray = Array.isArray, | |||
skipping to change at line 86 | skipping to change at line 87 | |||
}; | }; | |||
case 4: return function(accumulator, value, index, collection) { | case 4: return function(accumulator, value, index, collection) { | |||
return func.call(context, accumulator, value, index, collection); | return func.call(context, accumulator, value, index, collection); | |||
}; | }; | |||
} | } | |||
return function() { | return function() { | |||
return func.apply(context, arguments); | return func.apply(context, arguments); | |||
}; | }; | |||
}; | }; | |||
var builtinIteratee; | ||||
// An internal function to generate callbacks that can be applied to each | // An internal function to generate callbacks that can be applied to each | |||
// element in a collection, returning the desired result — either `identity`, | // element in a collection, returning the desired result — either `identity`, | |||
// an arbitrary callback, a property matcher, or a property accessor. | // an arbitrary callback, a property matcher, or a property accessor. | |||
var cb = function(value, context, argCount) { | var cb = function(value, context, argCount) { | |||
if (_.iteratee !== builtinIteratee) return _.iteratee(value, context); | ||||
if (value == null) return _.identity; | if (value == null) return _.identity; | |||
if (_.isFunction(value)) return optimizeCb(value, context, argCount); | if (_.isFunction(value)) return optimizeCb(value, context, argCount); | |||
if (_.isObject(value)) return _.matcher(value); | if (_.isObject(value)) return _.matcher(value); | |||
return _.property(value); | return _.property(value); | |||
}; | }; | |||
// An external wrapper for the internal callback generator | // External wrapper for our callback generator. Users may customize | |||
_.iteratee = function(value, context) { | // `_.iteratee` if they want additional predicate/iteratee shorthand styles. | |||
// This abstraction hides the internal-only argCount argument. | ||||
_.iteratee = builtinIteratee = function(value, context) { | ||||
return cb(value, context, Infinity); | return cb(value, context, Infinity); | |||
}; | }; | |||
// Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest- parameter.html) | // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest- parameter.html) | |||
// This accumulates the arguments passed into an array, after a given index. | // This accumulates the arguments passed into an array, after a given index. | |||
var restArgs = function(func, startIndex) { | var restArgs = function(func, startIndex) { | |||
startIndex = startIndex == null ? func.length - 1 : +startIndex; | startIndex = startIndex == null ? func.length - 1 : +startIndex; | |||
return function() { | return function() { | |||
var length = Math.max(arguments.length - startIndex, 0); | var length = Math.max(arguments.length - startIndex, 0); | |||
var rest = Array(length); | var rest = Array(length); | |||
skipping to change at line 221 | skipping to change at line 227 | |||
// **Reduce** builds up a single result from a list of values, aka `inject`, | // **Reduce** builds up a single result from a list of values, aka `inject`, | |||
// or `foldl`. | // or `foldl`. | |||
_.reduce = _.foldl = _.inject = createReduce(1); | _.reduce = _.foldl = _.inject = createReduce(1); | |||
// The right-associative version of reduce, also known as `foldr`. | // The right-associative version of reduce, also known as `foldr`. | |||
_.reduceRight = _.foldr = createReduce(-1); | _.reduceRight = _.foldr = createReduce(-1); | |||
// Return the first value which passes a truth test. Aliased as `detect`. | // Return the first value which passes a truth test. Aliased as `detect`. | |||
_.find = _.detect = function(obj, predicate, context) { | _.find = _.detect = function(obj, predicate, context) { | |||
var key; | var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey; | |||
if (isArrayLike(obj)) { | var key = keyFinder(obj, predicate, context); | |||
key = _.findIndex(obj, predicate, context); | ||||
} else { | ||||
key = _.findKey(obj, predicate, context); | ||||
} | ||||
if (key !== void 0 && key !== -1) return obj[key]; | if (key !== void 0 && key !== -1) return obj[key]; | |||
}; | }; | |||
// Return all the elements that pass a truth test. | // Return all the elements that pass a truth test. | |||
// Aliased as `select`. | // Aliased as `select`. | |||
_.filter = _.select = function(obj, predicate, context) { | _.filter = _.select = function(obj, predicate, context) { | |||
var results = []; | var results = []; | |||
predicate = cb(predicate, context); | predicate = cb(predicate, context); | |||
_.each(obj, function(value, index, list) { | _.each(obj, function(value, index, list) { | |||
if (predicate(value, index, list)) results.push(value); | if (predicate(value, index, list)) results.push(value); | |||
skipping to change at line 468 | skipping to change at line 470 | |||
result[pass ? 0 : 1].push(value); | result[pass ? 0 : 1].push(value); | |||
}, true); | }, true); | |||
// Array Functions | // Array Functions | |||
// --------------- | // --------------- | |||
// Get the first element of an array. Passing **n** will return the first N | // Get the first element of an array. Passing **n** will return the first N | |||
// values in the array. Aliased as `head` and `take`. The **guard** check | // values in the array. Aliased as `head` and `take`. The **guard** check | |||
// allows it to work with `_.map`. | // allows it to work with `_.map`. | |||
_.first = _.head = _.take = function(array, n, guard) { | _.first = _.head = _.take = function(array, n, guard) { | |||
if (array == null) return void 0; | if (array == null || array.length < 1) return void 0; | |||
if (n == null || guard) return array[0]; | if (n == null || guard) return array[0]; | |||
return _.initial(array, array.length - n); | return _.initial(array, array.length - n); | |||
}; | }; | |||
// Returns everything but the last entry of the array. Especially useful on | // Returns everything but the last entry of the array. Especially useful on | |||
// the arguments object. Passing **n** will return all the values in | // the arguments object. Passing **n** will return all the values in | |||
// the array, excluding the last N. | // the array, excluding the last N. | |||
_.initial = function(array, n, guard) { | _.initial = function(array, n, guard) { | |||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); | return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); | |||
}; | }; | |||
// Get the last element of an array. Passing **n** will return the last N | // Get the last element of an array. Passing **n** will return the last N | |||
// values in the array. | // values in the array. | |||
_.last = function(array, n, guard) { | _.last = function(array, n, guard) { | |||
if (array == null) return void 0; | if (array == null || array.length < 1) return void 0; | |||
if (n == null || guard) return array[array.length - 1]; | if (n == null || guard) return array[array.length - 1]; | |||
return _.rest(array, Math.max(0, array.length - n)); | return _.rest(array, Math.max(0, array.length - n)); | |||
}; | }; | |||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`. | // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. | |||
// Especially useful on the arguments object. Passing an **n** will return | // Especially useful on the arguments object. Passing an **n** will return | |||
// the rest N values in the array. | // the rest N values in the array. | |||
_.rest = _.tail = _.drop = function(array, n, guard) { | _.rest = _.tail = _.drop = function(array, n, guard) { | |||
return slice.call(array, n == null || guard ? 1 : n); | return slice.call(array, n == null || guard ? 1 : n); | |||
}; | }; | |||
// Trim out all falsy values from an array. | // Trim out all falsy values from an array. | |||
_.compact = function(array) { | _.compact = function(array) { | |||
return _.filter(array, _.identity); | return _.filter(array, Boolean); | |||
}; | }; | |||
// Internal implementation of a recursive `flatten` function. | // Internal implementation of a recursive `flatten` function. | |||
var flatten = function(input, shallow, strict, output) { | var flatten = function(input, shallow, strict, output) { | |||
output = output || []; | output = output || []; | |||
var idx = output.length; | var idx = output.length; | |||
for (var i = 0, length = getLength(input); i < length; i++) { | for (var i = 0, length = getLength(input); i < length; i++) { | |||
var value = input[i]; | var value = input[i]; | |||
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { | if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { | |||
// Flatten current level of array or arguments object | // Flatten current level of array or arguments object. | |||
if (shallow) { | if (shallow) { | |||
var j = 0, len = value.length; | var j = 0, len = value.length; | |||
while (j < len) output[idx++] = value[j++]; | while (j < len) output[idx++] = value[j++]; | |||
} else { | } else { | |||
flatten(value, shallow, strict, output); | flatten(value, shallow, strict, output); | |||
idx = output.length; | idx = output.length; | |||
} | } | |||
} else if (!strict) { | } else if (!strict) { | |||
output[idx++] = value; | output[idx++] = value; | |||
} | } | |||
skipping to change at line 595 | skipping to change at line 597 | |||
// Take the difference between one array and a number of other arrays. | // Take the difference between one array and a number of other arrays. | |||
// Only the elements present in just the first array will remain. | // Only the elements present in just the first array will remain. | |||
_.difference = restArgs(function(array, rest) { | _.difference = restArgs(function(array, rest) { | |||
rest = flatten(rest, true, true); | rest = flatten(rest, true, true); | |||
return _.filter(array, function(value){ | return _.filter(array, function(value){ | |||
return !_.contains(rest, value); | return !_.contains(rest, value); | |||
}); | }); | |||
}); | }); | |||
// Complement of _.zip. Unzip accepts an array of arrays and groups | // Complement of _.zip. Unzip accepts an array of arrays and groups | |||
// each array's elements on shared indices | // each array's elements on shared indices. | |||
_.unzip = function(array) { | _.unzip = function(array) { | |||
var length = array && _.max(array, getLength).length || 0; | var length = array && _.max(array, getLength).length || 0; | |||
var result = Array(length); | var result = Array(length); | |||
for (var index = 0; index < length; index++) { | for (var index = 0; index < length; index++) { | |||
result[index] = _.pluck(array, index); | result[index] = _.pluck(array, index); | |||
} | } | |||
return result; | return result; | |||
}; | }; | |||
skipping to change at line 625 | skipping to change at line 627 | |||
for (var i = 0, length = getLength(list); i < length; i++) { | for (var i = 0, length = getLength(list); i < length; i++) { | |||
if (values) { | if (values) { | |||
result[list[i]] = values[i]; | result[list[i]] = values[i]; | |||
} else { | } else { | |||
result[list[i][0]] = list[i][1]; | result[list[i][0]] = list[i][1]; | |||
} | } | |||
} | } | |||
return result; | return result; | |||
}; | }; | |||
// Generator function to create the findIndex and findLastIndex functions | // Generator function to create the findIndex and findLastIndex functions. | |||
var createPredicateIndexFinder = function(dir) { | var createPredicateIndexFinder = function(dir) { | |||
return function(array, predicate, context) { | return function(array, predicate, context) { | |||
predicate = cb(predicate, context); | predicate = cb(predicate, context); | |||
var length = getLength(array); | var length = getLength(array); | |||
var index = dir > 0 ? 0 : length - 1; | var index = dir > 0 ? 0 : length - 1; | |||
for (; index >= 0 && index < length; index += dir) { | for (; index >= 0 && index < length; index += dir) { | |||
if (predicate(array[index], index, array)) return index; | if (predicate(array[index], index, array)) return index; | |||
} | } | |||
return -1; | return -1; | |||
}; | }; | |||
}; | }; | |||
// Returns the first index on an array-like that passes a predicate test | // Returns the first index on an array-like that passes a predicate test. | |||
_.findIndex = createPredicateIndexFinder(1); | _.findIndex = createPredicateIndexFinder(1); | |||
_.findLastIndex = createPredicateIndexFinder(-1); | _.findLastIndex = createPredicateIndexFinder(-1); | |||
// Use a comparator function to figure out the smallest index at which | // 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. | // an object should be inserted so as to maintain order. Uses binary search. | |||
_.sortedIndex = function(array, obj, iteratee, context) { | _.sortedIndex = function(array, obj, iteratee, context) { | |||
iteratee = cb(iteratee, context, 1); | iteratee = cb(iteratee, context, 1); | |||
var value = iteratee(obj); | var value = iteratee(obj); | |||
var low = 0, high = getLength(array); | var low = 0, high = getLength(array); | |||
while (low < high) { | while (low < high) { | |||
var mid = Math.floor((low + high) / 2); | var mid = Math.floor((low + high) / 2); | |||
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; | if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; | |||
} | } | |||
return low; | return low; | |||
}; | }; | |||
// Generator function to create the indexOf and lastIndexOf functions | // Generator function to create the indexOf and lastIndexOf functions. | |||
var createIndexFinder = function(dir, predicateFind, sortedIndex) { | var createIndexFinder = function(dir, predicateFind, sortedIndex) { | |||
return function(array, item, idx) { | return function(array, item, idx) { | |||
var i = 0, length = getLength(array); | var i = 0, length = getLength(array); | |||
if (typeof idx == 'number') { | if (typeof idx == 'number') { | |||
if (dir > 0) { | if (dir > 0) { | |||
i = idx >= 0 ? idx : Math.max(idx + length, i); | i = idx >= 0 ? idx : Math.max(idx + length, i); | |||
} else { | } else { | |||
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; | length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; | |||
} | } | |||
} else if (sortedIndex && idx && length) { | } else if (sortedIndex && idx && length) { | |||
skipping to change at line 710 | skipping to change at line 712 | |||
var range = Array(length); | var range = Array(length); | |||
for (var idx = 0; idx < length; idx++, start += step) { | for (var idx = 0; idx < length; idx++, start += step) { | |||
range[idx] = start; | range[idx] = start; | |||
} | } | |||
return range; | return range; | |||
}; | }; | |||
// Split an **array** into several arrays containing **count** or less element s | // Split an **array** into several arrays containing **count** or less element s | |||
// of initial array | // of initial array. | |||
_.chunk = function(array, count) { | _.chunk = function(array, count) { | |||
if (count == null || count < 1) return []; | if (count == null || count < 1) return []; | |||
var result = []; | var result = []; | |||
var i = 0, length = array.length; | var i = 0, length = array.length; | |||
while (i < length) { | while (i < length) { | |||
result.push(slice.call(array, i, i += count)); | result.push(slice.call(array, i, i += count)); | |||
} | } | |||
return result; | return result; | |||
}; | }; | |||
// Function (ahem) Functions | // Function (ahem) Functions | |||
// ------------------ | // ------------------ | |||
// Determines whether to execute a function as a constructor | // Determines whether to execute a function as a constructor | |||
// or a normal function with the provided arguments | // or a normal function with the provided arguments. | |||
var executeBound = function(sourceFunc, boundFunc, context, callingContext, ar gs) { | var executeBound = function(sourceFunc, boundFunc, context, callingContext, ar gs) { | |||
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); | if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); | |||
var self = baseCreate(sourceFunc.prototype); | var self = baseCreate(sourceFunc.prototype); | |||
var result = sourceFunc.apply(self, args); | var result = sourceFunc.apply(self, args); | |||
if (_.isObject(result)) return result; | if (_.isObject(result)) return result; | |||
return self; | return self; | |||
}; | }; | |||
// Create a function bound to a given object (assigning `this`, and arguments, | // Create a function bound to a given object (assigning `this`, and arguments, | |||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if | // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if | |||
skipping to change at line 862 | skipping to change at line 864 | |||
// leading edge, instead of the trailing. | // leading edge, instead of the trailing. | |||
_.debounce = function(func, wait, immediate) { | _.debounce = function(func, wait, immediate) { | |||
var timeout, result; | var timeout, result; | |||
var later = function(context, args) { | var later = function(context, args) { | |||
timeout = null; | timeout = null; | |||
if (args) result = func.apply(context, args); | if (args) result = func.apply(context, args); | |||
}; | }; | |||
var debounced = restArgs(function(args) { | var debounced = restArgs(function(args) { | |||
var callNow = immediate && !timeout; | ||||
if (timeout) clearTimeout(timeout); | if (timeout) clearTimeout(timeout); | |||
if (callNow) { | if (immediate) { | |||
var callNow = !timeout; | ||||
timeout = setTimeout(later, wait); | timeout = setTimeout(later, wait); | |||
result = func.apply(this, args); | if (callNow) result = func.apply(this, args); | |||
} else if (!immediate) { | } else { | |||
timeout = _.delay(later, wait, this, args); | timeout = _.delay(later, wait, this, args); | |||
} | } | |||
return result; | return result; | |||
}); | }); | |||
debounced.cancel = function() { | debounced.cancel = function() { | |||
clearTimeout(timeout); | clearTimeout(timeout); | |||
timeout = null; | timeout = null; | |||
}; | }; | |||
skipping to change at line 962 | skipping to change at line 964 | |||
while (nonEnumIdx--) { | while (nonEnumIdx--) { | |||
prop = nonEnumerableProps[nonEnumIdx]; | prop = nonEnumerableProps[nonEnumIdx]; | |||
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { | if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { | |||
keys.push(prop); | keys.push(prop); | |||
} | } | |||
} | } | |||
}; | }; | |||
// Retrieve the names of an object's own properties. | // Retrieve the names of an object's own properties. | |||
// Delegates to **ECMAScript 5**'s native `Object.keys` | // Delegates to **ECMAScript 5**'s native `Object.keys`. | |||
_.keys = function(obj) { | _.keys = function(obj) { | |||
if (!_.isObject(obj)) return []; | if (!_.isObject(obj)) return []; | |||
if (nativeKeys) return nativeKeys(obj); | if (nativeKeys) return nativeKeys(obj); | |||
var keys = []; | var keys = []; | |||
for (var key in obj) if (_.has(obj, key)) keys.push(key); | for (var key in obj) if (_.has(obj, key)) keys.push(key); | |||
// Ahem, IE < 9. | // Ahem, IE < 9. | |||
if (hasEnumBug) collectNonEnumProps(obj, keys); | if (hasEnumBug) collectNonEnumProps(obj, keys); | |||
return keys; | return keys; | |||
}; | }; | |||
skipping to change at line 994 | skipping to change at line 996 | |||
_.values = function(obj) { | _.values = function(obj) { | |||
var keys = _.keys(obj); | var keys = _.keys(obj); | |||
var length = keys.length; | var length = keys.length; | |||
var values = Array(length); | var values = Array(length); | |||
for (var i = 0; i < length; i++) { | for (var i = 0; i < length; i++) { | |||
values[i] = obj[keys[i]]; | values[i] = obj[keys[i]]; | |||
} | } | |||
return values; | return values; | |||
}; | }; | |||
// Returns the results of applying the iteratee to each element of the object | // Returns the results of applying the iteratee to each element of the object. | |||
// In contrast to _.map it returns an object | // In contrast to _.map it returns an object. | |||
_.mapObject = function(obj, iteratee, context) { | _.mapObject = function(obj, iteratee, context) { | |||
iteratee = cb(iteratee, context); | iteratee = cb(iteratee, context); | |||
var keys = _.keys(obj), | var keys = _.keys(obj), | |||
length = keys.length, | length = keys.length, | |||
results = {}; | results = {}; | |||
for (var index = 0; index < length; index++) { | for (var index = 0; index < length; index++) { | |||
var currentKey = keys[index]; | var currentKey = keys[index]; | |||
results[currentKey] = iteratee(obj[currentKey], currentKey, obj); | results[currentKey] = iteratee(obj[currentKey], currentKey, obj); | |||
} | } | |||
return results; | return results; | |||
skipping to change at line 1030 | skipping to change at line 1032 | |||
_.invert = function(obj) { | _.invert = function(obj) { | |||
var result = {}; | var result = {}; | |||
var keys = _.keys(obj); | var keys = _.keys(obj); | |||
for (var i = 0, length = keys.length; i < length; i++) { | for (var i = 0, length = keys.length; i < length; i++) { | |||
result[obj[keys[i]]] = keys[i]; | result[obj[keys[i]]] = keys[i]; | |||
} | } | |||
return result; | return result; | |||
}; | }; | |||
// Return a sorted list of the function names available on the object. | // Return a sorted list of the function names available on the object. | |||
// Aliased as `methods` | // Aliased as `methods`. | |||
_.functions = _.methods = function(obj) { | _.functions = _.methods = function(obj) { | |||
var names = []; | var names = []; | |||
for (var key in obj) { | for (var key in obj) { | |||
if (_.isFunction(obj[key])) names.push(key); | if (_.isFunction(obj[key])) names.push(key); | |||
} | } | |||
return names.sort(); | return names.sort(); | |||
}; | }; | |||
// An internal function for creating assigner functions. | // An internal function for creating assigner functions. | |||
var createAssigner = function(keysFunc, defaults) { | var createAssigner = function(keysFunc, defaults) { | |||
skipping to change at line 1061 | skipping to change at line 1063 | |||
if (!defaults || obj[key] === void 0) obj[key] = source[key]; | if (!defaults || obj[key] === void 0) obj[key] = source[key]; | |||
} | } | |||
} | } | |||
return obj; | return obj; | |||
}; | }; | |||
}; | }; | |||
// Extend a given object with all the properties in passed-in object(s). | // Extend a given object with all the properties in passed-in object(s). | |||
_.extend = createAssigner(_.allKeys); | _.extend = createAssigner(_.allKeys); | |||
// Assigns a given object with all the own properties in the passed-in object( s) | // Assigns a given object with all the own properties in the passed-in object( s). | |||
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects /Object/assign) | // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects /Object/assign) | |||
_.extendOwn = _.assign = createAssigner(_.keys); | _.extendOwn = _.assign = createAssigner(_.keys); | |||
// Returns the first key on an object that passes a predicate test | // Returns the first key on an object that passes a predicate test. | |||
_.findKey = function(obj, predicate, context) { | _.findKey = function(obj, predicate, context) { | |||
predicate = cb(predicate, context); | predicate = cb(predicate, context); | |||
var keys = _.keys(obj), key; | var keys = _.keys(obj), key; | |||
for (var i = 0, length = keys.length; i < length; i++) { | for (var i = 0, length = keys.length; i < length; i++) { | |||
key = keys[i]; | key = keys[i]; | |||
if (predicate(obj[key], key, obj)) return key; | if (predicate(obj[key], key, obj)) return key; | |||
} | } | |||
}; | }; | |||
// Internal pick helper function to determine if `obj` has key `key`. | // Internal pick helper function to determine if `obj` has key `key`. | |||
skipping to change at line 1100 | skipping to change at line 1102 | |||
obj = Object(obj); | obj = Object(obj); | |||
} | } | |||
for (var i = 0, length = keys.length; i < length; i++) { | for (var i = 0, length = keys.length; i < length; i++) { | |||
var key = keys[i]; | var key = keys[i]; | |||
var value = obj[key]; | var value = obj[key]; | |||
if (iteratee(value, key, obj)) result[key] = value; | if (iteratee(value, key, obj)) result[key] = value; | |||
} | } | |||
return result; | return result; | |||
}); | }); | |||
// Return a copy of the object without the blacklisted properties. | // Return a copy of the object without the blacklisted properties. | |||
_.omit = restArgs(function(obj, keys) { | _.omit = restArgs(function(obj, keys) { | |||
var iteratee = keys[0], context; | var iteratee = keys[0], context; | |||
if (_.isFunction(iteratee)) { | if (_.isFunction(iteratee)) { | |||
iteratee = _.negate(iteratee); | iteratee = _.negate(iteratee); | |||
if (keys.length > 1) context = keys[1]; | if (keys.length > 1) context = keys[1]; | |||
} else { | } else { | |||
keys = _.map(flatten(keys, false, false), String); | keys = _.map(flatten(keys, false, false), String); | |||
iteratee = function(value, key) { | iteratee = function(value, key) { | |||
return !_.contains(keys, key); | return !_.contains(keys, key); | |||
}; | }; | |||
skipping to change at line 1187 | skipping to change at line 1189 | |||
switch (className) { | switch (className) { | |||
// Strings, numbers, regular expressions, dates, and booleans are compared by value. | // Strings, numbers, regular expressions, dates, and booleans are compared by value. | |||
case '[object RegExp]': | case '[object RegExp]': | |||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/ i') | // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/ i') | |||
case '[object String]': | case '[object String]': | |||
// Primitives and their corresponding object wrappers are equivalent; th us, `"5"` is | // Primitives and their corresponding object wrappers are equivalent; th us, `"5"` is | |||
// equivalent to `new String("5")`. | // equivalent to `new String("5")`. | |||
return '' + a === '' + b; | return '' + a === '' + b; | |||
case '[object Number]': | case '[object Number]': | |||
// `NaN`s are equivalent, but non-reflexive. | // `NaN`s are equivalent, but non-reflexive. | |||
// Object(NaN) is equivalent to NaN | // Object(NaN) is equivalent to NaN. | |||
if (+a !== +a) return +b !== +b; | if (+a !== +a) return +b !== +b; | |||
// An `egal` comparison is performed for other numeric values. | // An `egal` comparison is performed for other numeric values. | |||
return +a === 0 ? 1 / +a === 1 / b : +a === +b; | return +a === 0 ? 1 / +a === 1 / b : +a === +b; | |||
case '[object Date]': | case '[object Date]': | |||
case '[object Boolean]': | case '[object Boolean]': | |||
// Coerce dates and booleans to numeric primitive values. Dates are comp ared by their | // Coerce dates and booleans to numeric primitive values. Dates are comp ared by their | |||
// millisecond representations. Note that invalid dates with millisecond representations | // millisecond representations. Note that invalid dates with millisecond representations | |||
// of `NaN` are not equivalent. | // of `NaN` are not equivalent. | |||
return +a === +b; | return +a === +b; | |||
case '[object Symbol]': | ||||
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); | ||||
} | } | |||
var areArrays = className === '[object Array]'; | var areArrays = className === '[object Array]'; | |||
if (!areArrays) { | if (!areArrays) { | |||
if (typeof a != 'object' || typeof b != 'object') return false; | if (typeof a != 'object' || typeof b != 'object') return false; | |||
// Objects with different constructors are not equivalent, but `Object`s o r `Array`s | // Objects with different constructors are not equivalent, but `Object`s o r `Array`s | |||
// from different frames are. | // from different frames are. | |||
var aCtor = a.constructor, bCtor = b.constructor; | var aCtor = a.constructor, bCtor = b.constructor; | |||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && | if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && | |||
skipping to change at line 1287 | skipping to change at line 1291 | |||
_.isArray = nativeIsArray || function(obj) { | _.isArray = nativeIsArray || function(obj) { | |||
return toString.call(obj) === '[object Array]'; | return toString.call(obj) === '[object Array]'; | |||
}; | }; | |||
// Is a given variable an object? | // Is a given variable an object? | |||
_.isObject = function(obj) { | _.isObject = function(obj) { | |||
var type = typeof obj; | var type = typeof obj; | |||
return type === 'function' || type === 'object' && !!obj; | return type === 'function' || type === 'object' && !!obj; | |||
}; | }; | |||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDat | // Add some isType methods: isArguments, isFunction, isString, isNumber, isDat | |||
e, isRegExp, isError. | e, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet. | |||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error' | _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error' | |||
], function(name) { | , 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) { | |||
_['is' + name] = function(obj) { | _['is' + name] = function(obj) { | |||
return toString.call(obj) === '[object ' + name + ']'; | return toString.call(obj) === '[object ' + name + ']'; | |||
}; | }; | |||
}); | }); | |||
// Define a fallback version of the method in browsers (ahem, IE < 9), where | // Define a fallback version of the method in browsers (ahem, IE < 9), where | |||
// there isn't any inspectable "Arguments" type. | // there isn't any inspectable "Arguments" type. | |||
if (!_.isArguments(arguments)) { | if (!_.isArguments(arguments)) { | |||
_.isArguments = function(obj) { | _.isArguments = function(obj) { | |||
return _.has(obj, 'callee'); | return _.has(obj, 'callee'); | |||
skipping to change at line 1313 | skipping to change at line 1317 | |||
// IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). | // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). | |||
var nodelist = root.document && root.document.childNodes; | var nodelist = root.document && root.document.childNodes; | |||
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelis t != 'function') { | if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelis t != 'function') { | |||
_.isFunction = function(obj) { | _.isFunction = function(obj) { | |||
return typeof obj == 'function' || false; | return typeof obj == 'function' || false; | |||
}; | }; | |||
} | } | |||
// Is a given object a finite number? | // Is a given object a finite number? | |||
_.isFinite = function(obj) { | _.isFinite = function(obj) { | |||
return isFinite(obj) && !isNaN(parseFloat(obj)); | return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj)); | |||
}; | }; | |||
// Is the given value `NaN`? | // Is the given value `NaN`? | |||
_.isNaN = function(obj) { | _.isNaN = function(obj) { | |||
return _.isNumber(obj) && isNaN(obj); | return _.isNumber(obj) && isNaN(obj); | |||
}; | }; | |||
// Is a given value a boolean? | // Is a given value a boolean? | |||
_.isBoolean = function(obj) { | _.isBoolean = function(obj) { | |||
return obj === true || obj === false || toString.call(obj) === '[object Bool ean]'; | return obj === true || obj === false || toString.call(obj) === '[object Bool ean]'; | |||
skipping to change at line 1406 | skipping to change at line 1410 | |||
min = 0; | min = 0; | |||
} | } | |||
return min + Math.floor(Math.random() * (max - min + 1)); | return min + Math.floor(Math.random() * (max - min + 1)); | |||
}; | }; | |||
// A (possibly faster) way to get the current timestamp as an integer. | // A (possibly faster) way to get the current timestamp as an integer. | |||
_.now = Date.now || function() { | _.now = Date.now || function() { | |||
return new Date().getTime(); | return new Date().getTime(); | |||
}; | }; | |||
// List of HTML entities for escaping. | // List of HTML entities for escaping. | |||
var escapeMap = { | var escapeMap = { | |||
'&': '&', | '&': '&', | |||
'<': '<', | '<': '<', | |||
'>': '>', | '>': '>', | |||
'"': '"', | '"': '"', | |||
"'": ''', | "'": ''', | |||
'`': '`' | '`': '`' | |||
}; | }; | |||
var unescapeMap = _.invert(escapeMap); | var unescapeMap = _.invert(escapeMap); | |||
// Functions for escaping and unescaping strings to/from HTML interpolation. | // Functions for escaping and unescaping strings to/from HTML interpolation. | |||
var createEscaper = function(map) { | var createEscaper = function(map) { | |||
var escaper = function(match) { | var escaper = function(match) { | |||
return map[match]; | return map[match]; | |||
}; | }; | |||
// Regexes for identifying a key that needs to be escaped | // Regexes for identifying a key that needs to be escaped. | |||
var source = '(?:' + _.keys(map).join('|') + ')'; | var source = '(?:' + _.keys(map).join('|') + ')'; | |||
var testRegexp = RegExp(source); | var testRegexp = RegExp(source); | |||
var replaceRegexp = RegExp(source, 'g'); | var replaceRegexp = RegExp(source, 'g'); | |||
return function(string) { | return function(string) { | |||
string = string == null ? '' : '' + string; | string = string == null ? '' : '' + string; | |||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; | return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; | |||
}; | }; | |||
}; | }; | |||
_.escape = createEscaper(escapeMap); | _.escape = createEscaper(escapeMap); | |||
_.unescape = createEscaper(unescapeMap); | _.unescape = createEscaper(unescapeMap); | |||
skipping to change at line 1571 | skipping to change at line 1575 | |||
// Add your own custom functions to the Underscore object. | // Add your own custom functions to the Underscore object. | |||
_.mixin = function(obj) { | _.mixin = function(obj) { | |||
_.each(_.functions(obj), function(name) { | _.each(_.functions(obj), function(name) { | |||
var func = _[name] = obj[name]; | var func = _[name] = obj[name]; | |||
_.prototype[name] = function() { | _.prototype[name] = function() { | |||
var args = [this._wrapped]; | var args = [this._wrapped]; | |||
push.apply(args, arguments); | push.apply(args, arguments); | |||
return chainResult(this, func.apply(_, args)); | return chainResult(this, func.apply(_, args)); | |||
}; | }; | |||
}); | }); | |||
return _; | ||||
}; | }; | |||
// Add all of the Underscore functions to the wrapper object. | // Add all of the Underscore functions to the wrapper object. | |||
_.mixin(_); | _.mixin(_); | |||
// Add all mutator Array functions to the wrapper. | // Add all mutator Array functions to the wrapper. | |||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], funct ion(name) { | _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], funct ion(name) { | |||
var method = ArrayProto[name]; | var method = ArrayProto[name]; | |||
_.prototype[name] = function() { | _.prototype[name] = function() { | |||
var obj = this._wrapped; | var obj = this._wrapped; | |||
skipping to change at line 1605 | skipping to change at line 1610 | |||
// Extracts the result from a wrapped and chained object. | // Extracts the result from a wrapped and chained object. | |||
_.prototype.value = function() { | _.prototype.value = function() { | |||
return this._wrapped; | return this._wrapped; | |||
}; | }; | |||
// Provide unwrapping proxy for some methods used in engine operations | // Provide unwrapping proxy for some methods used in engine operations | |||
// such as arithmetic and JSON stringification. | // such as arithmetic and JSON stringification. | |||
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value; | _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; | |||
_.prototype.toString = function() { | _.prototype.toString = function() { | |||
return '' + this._wrapped; | return String(this._wrapped); | |||
}; | }; | |||
// AMD registration happens at the end for compatibility with AMD loaders | // AMD registration happens at the end for compatibility with AMD loaders | |||
// that may not enforce next-turn semantics on modules. Even though general | // that may not enforce next-turn semantics on modules. Even though general | |||
// practice for AMD registration is to be anonymous, underscore registers | // practice for AMD registration is to be anonymous, underscore registers | |||
// as a named module because, like jQuery, it is a base library that is | // as a named module because, like jQuery, it is a base library that is | |||
// popular enough to be bundled in a third party lib, but not be part of | // popular enough to be bundled in a third party lib, but not be part of | |||
// an AMD load request. Those cases could generate an error when an | // an AMD load request. Those cases could generate an error when an | |||
// anonymous define() is called outside of a loader request. | // anonymous define() is called outside of a loader request. | |||
if (typeof define == 'function' && define.amd) { | if (typeof define == 'function' && define.amd) { | |||
End of changes. 33 change blocks. | ||||
39 lines changed or deleted | 44 lines changed or added |