index.js
1 /** 2 * lodash (Custom Build) <https://lodash.com/> 3 * Build: `lodash modularize exports="npm" -o ./` 4 * Copyright jQuery Foundation and other contributors <https://jquery.org/> 5 * Released under MIT license <https://lodash.com/license> 6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> 7 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 8 */ 9 10 /** Used as references for various `Number` constants. */ 11 var MAX_SAFE_INTEGER = 9007199254740991; 12 13 /** `Object#toString` result references. */ 14 var argsTag = '[object Arguments]', 15 funcTag = '[object Function]', 16 genTag = '[object GeneratorFunction]'; 17 18 /** Used to detect unsigned integer values. */ 19 var reIsUint = /^(?:0|[1-9]\d*)$/; 20 21 /** 22 * A faster alternative to `Function#apply`, this function invokes `func` 23 * with the `this` binding of `thisArg` and the arguments of `args`. 24 * 25 * @private 26 * @param {Function} func The function to invoke. 27 * @param {*} thisArg The `this` binding of `func`. 28 * @param {Array} args The arguments to invoke `func` with. 29 * @returns {*} Returns the result of `func`. 30 */ 31 function apply(func, thisArg, args) { 32 switch (args.length) { 33 case 0: return func.call(thisArg); 34 case 1: return func.call(thisArg, args[0]); 35 case 2: return func.call(thisArg, args[0], args[1]); 36 case 3: return func.call(thisArg, args[0], args[1], args[2]); 37 } 38 return func.apply(thisArg, args); 39 } 40 41 /** 42 * The base implementation of `_.times` without support for iteratee shorthands 43 * or max array length checks. 44 * 45 * @private 46 * @param {number} n The number of times to invoke `iteratee`. 47 * @param {Function} iteratee The function invoked per iteration. 48 * @returns {Array} Returns the array of results. 49 */ 50 function baseTimes(n, iteratee) { 51 var index = -1, 52 result = Array(n); 53 54 while (++index < n) { 55 result[index] = iteratee(index); 56 } 57 return result; 58 } 59 60 /** Used for built-in method references. */ 61 var objectProto = Object.prototype; 62 63 /** Used to check objects for own properties. */ 64 var hasOwnProperty = objectProto.hasOwnProperty; 65 66 /** 67 * Used to resolve the 68 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 69 * of values. 70 */ 71 var objectToString = objectProto.toString; 72 73 /** Built-in value references. */ 74 var propertyIsEnumerable = objectProto.propertyIsEnumerable; 75 76 /* Built-in method references for those with the same name as other `lodash` methods. */ 77 var nativeMax = Math.max; 78 79 /** 80 * Creates an array of the enumerable property names of the array-like `value`. 81 * 82 * @private 83 * @param {*} value The value to query. 84 * @param {boolean} inherited Specify returning inherited property names. 85 * @returns {Array} Returns the array of property names. 86 */ 87 function arrayLikeKeys(value, inherited) { 88 // Safari 8.1 makes `arguments.callee` enumerable in strict mode. 89 // Safari 9 makes `arguments.length` enumerable in strict mode. 90 var result = (isArray(value) || isArguments(value)) 91 ? baseTimes(value.length, String) 92 : []; 93 94 var length = result.length, 95 skipIndexes = !!length; 96 97 for (var key in value) { 98 if ((inherited || hasOwnProperty.call(value, key)) && 99 !(skipIndexes && (key == 'length' || isIndex(key, length)))) { 100 result.push(key); 101 } 102 } 103 return result; 104 } 105 106 /** 107 * Used by `_.defaults` to customize its `_.assignIn` use. 108 * 109 * @private 110 * @param {*} objValue The destination value. 111 * @param {*} srcValue The source value. 112 * @param {string} key The key of the property to assign. 113 * @param {Object} object The parent object of `objValue`. 114 * @returns {*} Returns the value to assign. 115 */ 116 function assignInDefaults(objValue, srcValue, key, object) { 117 if (objValue === undefined || 118 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { 119 return srcValue; 120 } 121 return objValue; 122 } 123 124 /** 125 * Assigns `value` to `key` of `object` if the existing value is not equivalent 126 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) 127 * for equality comparisons. 128 * 129 * @private 130 * @param {Object} object The object to modify. 131 * @param {string} key The key of the property to assign. 132 * @param {*} value The value to assign. 133 */ 134 function assignValue(object, key, value) { 135 var objValue = object[key]; 136 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || 137 (value === undefined && !(key in object))) { 138 object[key] = value; 139 } 140 } 141 142 /** 143 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. 144 * 145 * @private 146 * @param {Object} object The object to query. 147 * @returns {Array} Returns the array of property names. 148 */ 149 function baseKeysIn(object) { 150 if (!isObject(object)) { 151 return nativeKeysIn(object); 152 } 153 var isProto = isPrototype(object), 154 result = []; 155 156 for (var key in object) { 157 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { 158 result.push(key); 159 } 160 } 161 return result; 162 } 163 164 /** 165 * The base implementation of `_.rest` which doesn't validate or coerce arguments. 166 * 167 * @private 168 * @param {Function} func The function to apply a rest parameter to. 169 * @param {number} [start=func.length-1] The start position of the rest parameter. 170 * @returns {Function} Returns the new function. 171 */ 172 function baseRest(func, start) { 173 start = nativeMax(start === undefined ? (func.length - 1) : start, 0); 174 return function() { 175 var args = arguments, 176 index = -1, 177 length = nativeMax(args.length - start, 0), 178 array = Array(length); 179 180 while (++index < length) { 181 array[index] = args[start + index]; 182 } 183 index = -1; 184 var otherArgs = Array(start + 1); 185 while (++index < start) { 186 otherArgs[index] = args[index]; 187 } 188 otherArgs[start] = array; 189 return apply(func, this, otherArgs); 190 }; 191 } 192 193 /** 194 * Copies properties of `source` to `object`. 195 * 196 * @private 197 * @param {Object} source The object to copy properties from. 198 * @param {Array} props The property identifiers to copy. 199 * @param {Object} [object={}] The object to copy properties to. 200 * @param {Function} [customizer] The function to customize copied values. 201 * @returns {Object} Returns `object`. 202 */ 203 function copyObject(source, props, object, customizer) { 204 object || (object = {}); 205 206 var index = -1, 207 length = props.length; 208 209 while (++index < length) { 210 var key = props[index]; 211 212 var newValue = customizer 213 ? customizer(object[key], source[key], key, object, source) 214 : undefined; 215 216 assignValue(object, key, newValue === undefined ? source[key] : newValue); 217 } 218 return object; 219 } 220 221 /** 222 * Creates a function like `_.assign`. 223 * 224 * @private 225 * @param {Function} assigner The function to assign values. 226 * @returns {Function} Returns the new assigner function. 227 */ 228 function createAssigner(assigner) { 229 return baseRest(function(object, sources) { 230 var index = -1, 231 length = sources.length, 232 customizer = length > 1 ? sources[length - 1] : undefined, 233 guard = length > 2 ? sources[2] : undefined; 234 235 customizer = (assigner.length > 3 && typeof customizer == 'function') 236 ? (length--, customizer) 237 : undefined; 238 239 if (guard && isIterateeCall(sources[0], sources[1], guard)) { 240 customizer = length < 3 ? undefined : customizer; 241 length = 1; 242 } 243 object = Object(object); 244 while (++index < length) { 245 var source = sources[index]; 246 if (source) { 247 assigner(object, source, index, customizer); 248 } 249 } 250 return object; 251 }); 252 } 253 254 /** 255 * Checks if `value` is a valid array-like index. 256 * 257 * @private 258 * @param {*} value The value to check. 259 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. 260 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. 261 */ 262 function isIndex(value, length) { 263 length = length == null ? MAX_SAFE_INTEGER : length; 264 return !!length && 265 (typeof value == 'number' || reIsUint.test(value)) && 266 (value > -1 && value % 1 == 0 && value < length); 267 } 268 269 /** 270 * Checks if the given arguments are from an iteratee call. 271 * 272 * @private 273 * @param {*} value The potential iteratee value argument. 274 * @param {*} index The potential iteratee index or key argument. 275 * @param {*} object The potential iteratee object argument. 276 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, 277 * else `false`. 278 */ 279 function isIterateeCall(value, index, object) { 280 if (!isObject(object)) { 281 return false; 282 } 283 var type = typeof index; 284 if (type == 'number' 285 ? (isArrayLike(object) && isIndex(index, object.length)) 286 : (type == 'string' && index in object) 287 ) { 288 return eq(object[index], value); 289 } 290 return false; 291 } 292 293 /** 294 * Checks if `value` is likely a prototype object. 295 * 296 * @private 297 * @param {*} value The value to check. 298 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. 299 */ 300 function isPrototype(value) { 301 var Ctor = value && value.constructor, 302 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; 303 304 return value === proto; 305 } 306 307 /** 308 * This function is like 309 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) 310 * except that it includes inherited enumerable properties. 311 * 312 * @private 313 * @param {Object} object The object to query. 314 * @returns {Array} Returns the array of property names. 315 */ 316 function nativeKeysIn(object) { 317 var result = []; 318 if (object != null) { 319 for (var key in Object(object)) { 320 result.push(key); 321 } 322 } 323 return result; 324 } 325 326 /** 327 * Performs a 328 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) 329 * comparison between two values to determine if they are equivalent. 330 * 331 * @static 332 * @memberOf _ 333 * @since 4.0.0 334 * @category Lang 335 * @param {*} value The value to compare. 336 * @param {*} other The other value to compare. 337 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. 338 * @example 339 * 340 * var object = { 'a': 1 }; 341 * var other = { 'a': 1 }; 342 * 343 * _.eq(object, object); 344 * // => true 345 * 346 * _.eq(object, other); 347 * // => false 348 * 349 * _.eq('a', 'a'); 350 * // => true 351 * 352 * _.eq('a', Object('a')); 353 * // => false 354 * 355 * _.eq(NaN, NaN); 356 * // => true 357 */ 358 function eq(value, other) { 359 return value === other || (value !== value && other !== other); 360 } 361 362 /** 363 * Checks if `value` is likely an `arguments` object. 364 * 365 * @static 366 * @memberOf _ 367 * @since 0.1.0 368 * @category Lang 369 * @param {*} value The value to check. 370 * @returns {boolean} Returns `true` if `value` is an `arguments` object, 371 * else `false`. 372 * @example 373 * 374 * _.isArguments(function() { return arguments; }()); 375 * // => true 376 * 377 * _.isArguments([1, 2, 3]); 378 * // => false 379 */ 380 function isArguments(value) { 381 // Safari 8.1 makes `arguments.callee` enumerable in strict mode. 382 return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && 383 (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); 384 } 385 386 /** 387 * Checks if `value` is classified as an `Array` object. 388 * 389 * @static 390 * @memberOf _ 391 * @since 0.1.0 392 * @category Lang 393 * @param {*} value The value to check. 394 * @returns {boolean} Returns `true` if `value` is an array, else `false`. 395 * @example 396 * 397 * _.isArray([1, 2, 3]); 398 * // => true 399 * 400 * _.isArray(document.body.children); 401 * // => false 402 * 403 * _.isArray('abc'); 404 * // => false 405 * 406 * _.isArray(_.noop); 407 * // => false 408 */ 409 var isArray = Array.isArray; 410 411 /** 412 * Checks if `value` is array-like. A value is considered array-like if it's 413 * not a function and has a `value.length` that's an integer greater than or 414 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. 415 * 416 * @static 417 * @memberOf _ 418 * @since 4.0.0 419 * @category Lang 420 * @param {*} value The value to check. 421 * @returns {boolean} Returns `true` if `value` is array-like, else `false`. 422 * @example 423 * 424 * _.isArrayLike([1, 2, 3]); 425 * // => true 426 * 427 * _.isArrayLike(document.body.children); 428 * // => true 429 * 430 * _.isArrayLike('abc'); 431 * // => true 432 * 433 * _.isArrayLike(_.noop); 434 * // => false 435 */ 436 function isArrayLike(value) { 437 return value != null && isLength(value.length) && !isFunction(value); 438 } 439 440 /** 441 * This method is like `_.isArrayLike` except that it also checks if `value` 442 * is an object. 443 * 444 * @static 445 * @memberOf _ 446 * @since 4.0.0 447 * @category Lang 448 * @param {*} value The value to check. 449 * @returns {boolean} Returns `true` if `value` is an array-like object, 450 * else `false`. 451 * @example 452 * 453 * _.isArrayLikeObject([1, 2, 3]); 454 * // => true 455 * 456 * _.isArrayLikeObject(document.body.children); 457 * // => true 458 * 459 * _.isArrayLikeObject('abc'); 460 * // => false 461 * 462 * _.isArrayLikeObject(_.noop); 463 * // => false 464 */ 465 function isArrayLikeObject(value) { 466 return isObjectLike(value) && isArrayLike(value); 467 } 468 469 /** 470 * Checks if `value` is classified as a `Function` object. 471 * 472 * @static 473 * @memberOf _ 474 * @since 0.1.0 475 * @category Lang 476 * @param {*} value The value to check. 477 * @returns {boolean} Returns `true` if `value` is a function, else `false`. 478 * @example 479 * 480 * _.isFunction(_); 481 * // => true 482 * 483 * _.isFunction(/abc/); 484 * // => false 485 */ 486 function isFunction(value) { 487 // The use of `Object#toString` avoids issues with the `typeof` operator 488 // in Safari 8-9 which returns 'object' for typed array and other constructors. 489 var tag = isObject(value) ? objectToString.call(value) : ''; 490 return tag == funcTag || tag == genTag; 491 } 492 493 /** 494 * Checks if `value` is a valid array-like length. 495 * 496 * **Note:** This method is loosely based on 497 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). 498 * 499 * @static 500 * @memberOf _ 501 * @since 4.0.0 502 * @category Lang 503 * @param {*} value The value to check. 504 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. 505 * @example 506 * 507 * _.isLength(3); 508 * // => true 509 * 510 * _.isLength(Number.MIN_VALUE); 511 * // => false 512 * 513 * _.isLength(Infinity); 514 * // => false 515 * 516 * _.isLength('3'); 517 * // => false 518 */ 519 function isLength(value) { 520 return typeof value == 'number' && 521 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; 522 } 523 524 /** 525 * Checks if `value` is the 526 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) 527 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) 528 * 529 * @static 530 * @memberOf _ 531 * @since 0.1.0 532 * @category Lang 533 * @param {*} value The value to check. 534 * @returns {boolean} Returns `true` if `value` is an object, else `false`. 535 * @example 536 * 537 * _.isObject({}); 538 * // => true 539 * 540 * _.isObject([1, 2, 3]); 541 * // => true 542 * 543 * _.isObject(_.noop); 544 * // => true 545 * 546 * _.isObject(null); 547 * // => false 548 */ 549 function isObject(value) { 550 var type = typeof value; 551 return !!value && (type == 'object' || type == 'function'); 552 } 553 554 /** 555 * Checks if `value` is object-like. A value is object-like if it's not `null` 556 * and has a `typeof` result of "object". 557 * 558 * @static 559 * @memberOf _ 560 * @since 4.0.0 561 * @category Lang 562 * @param {*} value The value to check. 563 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 564 * @example 565 * 566 * _.isObjectLike({}); 567 * // => true 568 * 569 * _.isObjectLike([1, 2, 3]); 570 * // => true 571 * 572 * _.isObjectLike(_.noop); 573 * // => false 574 * 575 * _.isObjectLike(null); 576 * // => false 577 */ 578 function isObjectLike(value) { 579 return !!value && typeof value == 'object'; 580 } 581 582 /** 583 * This method is like `_.assignIn` except that it accepts `customizer` 584 * which is invoked to produce the assigned values. If `customizer` returns 585 * `undefined`, assignment is handled by the method instead. The `customizer` 586 * is invoked with five arguments: (objValue, srcValue, key, object, source). 587 * 588 * **Note:** This method mutates `object`. 589 * 590 * @static 591 * @memberOf _ 592 * @since 4.0.0 593 * @alias extendWith 594 * @category Object 595 * @param {Object} object The destination object. 596 * @param {...Object} sources The source objects. 597 * @param {Function} [customizer] The function to customize assigned values. 598 * @returns {Object} Returns `object`. 599 * @see _.assignWith 600 * @example 601 * 602 * function customizer(objValue, srcValue) { 603 * return _.isUndefined(objValue) ? srcValue : objValue; 604 * } 605 * 606 * var defaults = _.partialRight(_.assignInWith, customizer); 607 * 608 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); 609 * // => { 'a': 1, 'b': 2 } 610 */ 611 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { 612 copyObject(source, keysIn(source), object, customizer); 613 }); 614 615 /** 616 * Assigns own and inherited enumerable string keyed properties of source 617 * objects to the destination object for all destination properties that 618 * resolve to `undefined`. Source objects are applied from left to right. 619 * Once a property is set, additional values of the same property are ignored. 620 * 621 * **Note:** This method mutates `object`. 622 * 623 * @static 624 * @since 0.1.0 625 * @memberOf _ 626 * @category Object 627 * @param {Object} object The destination object. 628 * @param {...Object} [sources] The source objects. 629 * @returns {Object} Returns `object`. 630 * @see _.defaultsDeep 631 * @example 632 * 633 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); 634 * // => { 'a': 1, 'b': 2 } 635 */ 636 var defaults = baseRest(function(args) { 637 args.push(undefined, assignInDefaults); 638 return apply(assignInWith, undefined, args); 639 }); 640 641 /** 642 * Creates an array of the own and inherited enumerable property names of `object`. 643 * 644 * **Note:** Non-object values are coerced to objects. 645 * 646 * @static 647 * @memberOf _ 648 * @since 3.0.0 649 * @category Object 650 * @param {Object} object The object to query. 651 * @returns {Array} Returns the array of property names. 652 * @example 653 * 654 * function Foo() { 655 * this.a = 1; 656 * this.b = 2; 657 * } 658 * 659 * Foo.prototype.c = 3; 660 * 661 * _.keysIn(new Foo); 662 * // => ['a', 'b', 'c'] (iteration order is not guaranteed) 663 */ 664 function keysIn(object) { 665 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); 666 } 667 668 module.exports = defaults;