PageRenderTime 30ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/files/lodash/2.3.0/lodash.underscore.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1648 lines | 1136 code | 86 blank | 426 comment | 163 complexity | 95b772b0b7c2bc60e1a372fe8f60e2b8 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 2.3.0 (Custom Build) <http://lodash.com/>
  4. * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8. * Available under MIT license <http://lodash.com/license>
  9. */
  10. ;(function() {
  11. /** Used as a safe reference for `undefined` in pre ES5 environments */
  12. var undefined;
  13. /** Used to generate unique IDs */
  14. var idCounter = 0;
  15. /** Used internally to indicate various things */
  16. var indicatorObject = {};
  17. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  18. var keyPrefix = +new Date + '';
  19. /** Used to match "interpolate" template delimiters */
  20. var reInterpolate = /<%=([\s\S]+?)%>/g;
  21. /** Used to ensure capturing order of template delimiters */
  22. var reNoMatch = /($^)/;
  23. /** Used to match unescaped characters in compiled string literals */
  24. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  25. /** `Object#toString` result shortcuts */
  26. var argsClass = '[object Arguments]',
  27. arrayClass = '[object Array]',
  28. boolClass = '[object Boolean]',
  29. dateClass = '[object Date]',
  30. funcClass = '[object Function]',
  31. numberClass = '[object Number]',
  32. objectClass = '[object Object]',
  33. regexpClass = '[object RegExp]',
  34. stringClass = '[object String]';
  35. /** Used to determine if values are of the language type Object */
  36. var objectTypes = {
  37. 'boolean': false,
  38. 'function': true,
  39. 'object': true,
  40. 'number': false,
  41. 'string': false,
  42. 'undefined': false
  43. };
  44. /** Used to escape characters for inclusion in compiled string literals */
  45. var stringEscapes = {
  46. '\\': '\\',
  47. "'": "'",
  48. '\n': 'n',
  49. '\r': 'r',
  50. '\t': 't',
  51. '\u2028': 'u2028',
  52. '\u2029': 'u2029'
  53. };
  54. /** Used as a reference to the global object */
  55. var root = (objectTypes[typeof window] && window) || this;
  56. /** Detect free variable `exports` */
  57. var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
  58. /** Detect free variable `module` */
  59. var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
  60. /** Detect the popular CommonJS extension `module.exports` */
  61. var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
  62. /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
  63. var freeGlobal = objectTypes[typeof global] && global;
  64. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  65. root = freeGlobal;
  66. }
  67. /*--------------------------------------------------------------------------*/
  68. /**
  69. * The base implementation of `_.indexOf` without support for binary searches
  70. * or `fromIndex` constraints.
  71. *
  72. * @private
  73. * @param {Array} array The array to search.
  74. * @param {*} value The value to search for.
  75. * @param {number} [fromIndex=0] The index to search from.
  76. * @returns {number} Returns the index of the matched value or `-1`.
  77. */
  78. function baseIndexOf(array, value, fromIndex) {
  79. var index = (fromIndex || 0) - 1,
  80. length = array ? array.length : 0;
  81. while (++index < length) {
  82. if (array[index] === value) {
  83. return index;
  84. }
  85. }
  86. return -1;
  87. }
  88. /**
  89. * Used by `sortBy` to compare transformed `collection` elements, stable sorting
  90. * them in ascending order.
  91. *
  92. * @private
  93. * @param {Object} a The object to compare to `b`.
  94. * @param {Object} b The object to compare to `a`.
  95. * @returns {number} Returns the sort order indicator of `1` or `-1`.
  96. */
  97. function compareAscending(a, b) {
  98. var ac = a.criteria,
  99. bc = b.criteria;
  100. // ensure a stable sort in V8 and other engines
  101. // http://code.google.com/p/v8/issues/detail?id=90
  102. if (ac !== bc) {
  103. if (ac > bc || typeof ac == 'undefined') {
  104. return 1;
  105. }
  106. if (ac < bc || typeof bc == 'undefined') {
  107. return -1;
  108. }
  109. }
  110. // The JS engine embedded in Adobe applications like InDesign has a buggy
  111. // `Array#sort` implementation that causes it, under certain circumstances,
  112. // to return the same value for `a` and `b`.
  113. // See https://github.com/jashkenas/underscore/pull/1247
  114. return a.index - b.index;
  115. }
  116. /**
  117. * Used by `template` to escape characters for inclusion in compiled
  118. * string literals.
  119. *
  120. * @private
  121. * @param {string} match The matched character to escape.
  122. * @returns {string} Returns the escaped character.
  123. */
  124. function escapeStringChar(match) {
  125. return '\\' + stringEscapes[match];
  126. }
  127. /**
  128. * Slices the `collection` from the `start` index up to, but not including,
  129. * the `end` index.
  130. *
  131. * Note: This function is used instead of `Array#slice` to support node lists
  132. * in IE < 9 and to ensure dense arrays are returned.
  133. *
  134. * @private
  135. * @param {Array|Object|string} collection The collection to slice.
  136. * @param {number} start The start index.
  137. * @param {number} end The end index.
  138. * @returns {Array} Returns the new array.
  139. */
  140. function slice(array, start, end) {
  141. start || (start = 0);
  142. if (typeof end == 'undefined') {
  143. end = array ? array.length : 0;
  144. }
  145. var index = -1,
  146. length = end - start || 0,
  147. result = Array(length < 0 ? 0 : length);
  148. while (++index < length) {
  149. result[index] = array[start + index];
  150. }
  151. return result;
  152. }
  153. /*--------------------------------------------------------------------------*/
  154. /**
  155. * Used for `Array` method references.
  156. *
  157. * Normally `Array.prototype` would suffice, however, using an array literal
  158. * avoids issues in Narwhal.
  159. */
  160. var arrayRef = [];
  161. /** Used for native method references */
  162. var objectProto = Object.prototype;
  163. /** Used to restore the original `_` reference in `noConflict` */
  164. var oldDash = root._;
  165. /** Used to resolve the internal [[Class]] of values */
  166. var toString = objectProto.toString;
  167. /** Used to detect if a method is native */
  168. var reNative = RegExp('^' +
  169. String(toString)
  170. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  171. .replace(/toString| for [^\]]+/g, '.*?') + '$'
  172. );
  173. /** Native method shortcuts */
  174. var ceil = Math.ceil,
  175. floor = Math.floor,
  176. hasOwnProperty = objectProto.hasOwnProperty,
  177. now = reNative.test(now = Date.now) && now || function() { return +new Date; },
  178. push = arrayRef.push,
  179. propertyIsEnumerable = objectProto.propertyIsEnumerable;
  180. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  181. var nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
  182. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  183. nativeIsFinite = root.isFinite,
  184. nativeIsNaN = root.isNaN,
  185. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  186. nativeMax = Math.max,
  187. nativeMin = Math.min,
  188. nativeRandom = Math.random;
  189. /*--------------------------------------------------------------------------*/
  190. /**
  191. * Creates a `lodash` object which wraps the given value to enable intuitive
  192. * method chaining.
  193. *
  194. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  195. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  196. * and `unshift`
  197. *
  198. * Chaining is supported in custom builds as long as the `value` method is
  199. * implicitly or explicitly included in the build.
  200. *
  201. * The chainable wrapper functions are:
  202. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  203. * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
  204. * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
  205. * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
  206. * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
  207. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  208. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
  209. * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
  210. * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
  211. * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
  212. * and `zip`
  213. *
  214. * The non-chainable wrapper functions are:
  215. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
  216. * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
  217. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
  218. * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
  219. * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
  220. * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
  221. * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
  222. * `template`, `unescape`, `uniqueId`, and `value`
  223. *
  224. * The wrapper functions `first` and `last` return wrapped values when `n` is
  225. * provided, otherwise they return unwrapped values.
  226. *
  227. * Explicit chaining can be enabled by using the `_.chain` method.
  228. *
  229. * @name _
  230. * @constructor
  231. * @category Chaining
  232. * @param {*} value The value to wrap in a `lodash` instance.
  233. * @returns {Object} Returns a `lodash` instance.
  234. * @example
  235. *
  236. * var wrapped = _([1, 2, 3]);
  237. *
  238. * // returns an unwrapped value
  239. * wrapped.reduce(function(sum, num) {
  240. * return sum + num;
  241. * });
  242. * // => 6
  243. *
  244. * // returns a wrapped value
  245. * var squares = wrapped.map(function(num) {
  246. * return num * num;
  247. * });
  248. *
  249. * _.isArray(squares);
  250. * // => false
  251. *
  252. * _.isArray(squares.value());
  253. * // => true
  254. */
  255. function lodash(value) {
  256. return (value instanceof lodash)
  257. ? value
  258. : new lodashWrapper(value);
  259. }
  260. /**
  261. * A fast path for creating `lodash` wrapper objects.
  262. *
  263. * @private
  264. * @param {*} value The value to wrap in a `lodash` instance.
  265. * @param {boolean} chainAll A flag to enable chaining for all methods
  266. * @returns {Object} Returns a `lodash` instance.
  267. */
  268. function lodashWrapper(value, chainAll) {
  269. this.__chain__ = !!chainAll;
  270. this.__wrapped__ = value;
  271. }
  272. // ensure `new lodashWrapper` is an instance of `lodash`
  273. lodashWrapper.prototype = lodash.prototype;
  274. /**
  275. * An object used to flag environments features.
  276. *
  277. * @static
  278. * @memberOf _
  279. * @type Object
  280. */
  281. var support = {};
  282. (function() {
  283. var object = { '0': 1, 'length': 1 };
  284. /**
  285. * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
  286. *
  287. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  288. * and `splice()` functions that fail to remove the last element, `value[0]`,
  289. * of array-like objects even though the `length` property is set to `0`.
  290. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  291. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  292. *
  293. * @memberOf _.support
  294. * @type boolean
  295. */
  296. support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
  297. }(1));
  298. /**
  299. * By default, the template delimiters used by Lo-Dash are similar to those in
  300. * embedded Ruby (ERB). Change the following template settings to use alternative
  301. * delimiters.
  302. *
  303. * @static
  304. * @memberOf _
  305. * @type Object
  306. */
  307. lodash.templateSettings = {
  308. /**
  309. * Used to detect `data` property values to be HTML-escaped.
  310. *
  311. * @memberOf _.templateSettings
  312. * @type RegExp
  313. */
  314. 'escape': /<%-([\s\S]+?)%>/g,
  315. /**
  316. * Used to detect code to be evaluated.
  317. *
  318. * @memberOf _.templateSettings
  319. * @type RegExp
  320. */
  321. 'evaluate': /<%([\s\S]+?)%>/g,
  322. /**
  323. * Used to detect `data` property values to inject.
  324. *
  325. * @memberOf _.templateSettings
  326. * @type RegExp
  327. */
  328. 'interpolate': reInterpolate,
  329. /**
  330. * Used to reference the data object in the template text.
  331. *
  332. * @memberOf _.templateSettings
  333. * @type string
  334. */
  335. 'variable': ''
  336. };
  337. /*--------------------------------------------------------------------------*/
  338. /**
  339. * The base implementation of `_.bind` that creates the bound function and
  340. * sets its meta data.
  341. *
  342. * @private
  343. * @param {Array} bindData The bind data array.
  344. * @returns {Function} Returns the new bound function.
  345. */
  346. function baseBind(bindData) {
  347. var func = bindData[0],
  348. partialArgs = bindData[2],
  349. thisArg = bindData[4];
  350. function bound() {
  351. // `Function#bind` spec
  352. // http://es5.github.io/#x15.3.4.5
  353. if (partialArgs) {
  354. var args = partialArgs.slice();
  355. push.apply(args, arguments);
  356. }
  357. // mimic the constructor's `return` behavior
  358. // http://es5.github.io/#x13.2.2
  359. if (this instanceof bound) {
  360. // ensure `new bound` is an instance of `func`
  361. var thisBinding = baseCreate(func.prototype),
  362. result = func.apply(thisBinding, args || arguments);
  363. return isObject(result) ? result : thisBinding;
  364. }
  365. return func.apply(thisArg, args || arguments);
  366. }
  367. return bound;
  368. }
  369. /**
  370. * The base implementation of `_.create` without support for assigning
  371. * properties to the created object.
  372. *
  373. * @private
  374. * @param {Object} prototype The object to inherit from.
  375. * @returns {Object} Returns the new object.
  376. */
  377. function baseCreate(prototype, properties) {
  378. return isObject(prototype) ? nativeCreate(prototype) : {};
  379. }
  380. // fallback for browsers without `Object.create`
  381. if (!nativeCreate) {
  382. baseCreate = (function() {
  383. function Object() {}
  384. return function(prototype) {
  385. if (isObject(prototype)) {
  386. Object.prototype = prototype;
  387. var result = new Object;
  388. Object.prototype = null;
  389. }
  390. return result || root.Object();
  391. };
  392. }());
  393. }
  394. /**
  395. * The base implementation of `_.createCallback` without support for creating
  396. * "_.pluck" or "_.where" style callbacks.
  397. *
  398. * @private
  399. * @param {*} [func=identity] The value to convert to a callback.
  400. * @param {*} [thisArg] The `this` binding of the created callback.
  401. * @param {number} [argCount] The number of arguments the callback accepts.
  402. * @returns {Function} Returns a callback function.
  403. */
  404. function baseCreateCallback(func, thisArg, argCount) {
  405. if (typeof func != 'function') {
  406. return identity;
  407. }
  408. // exit early for no `thisArg` or already bound by `Function#bind`
  409. if (typeof thisArg == 'undefined' || !('prototype' in func)) {
  410. return func;
  411. }
  412. switch (argCount) {
  413. case 1: return function(value) {
  414. return func.call(thisArg, value);
  415. };
  416. case 2: return function(a, b) {
  417. return func.call(thisArg, a, b);
  418. };
  419. case 3: return function(value, index, collection) {
  420. return func.call(thisArg, value, index, collection);
  421. };
  422. case 4: return function(accumulator, value, index, collection) {
  423. return func.call(thisArg, accumulator, value, index, collection);
  424. };
  425. }
  426. return bind(func, thisArg);
  427. }
  428. /**
  429. * The base implementation of `createWrapper` that creates the wrapper and
  430. * sets its meta data.
  431. *
  432. * @private
  433. * @param {Array} bindData The bind data array.
  434. * @returns {Function} Returns the new function.
  435. */
  436. function baseCreateWrapper(bindData) {
  437. var func = bindData[0],
  438. bitmask = bindData[1],
  439. partialArgs = bindData[2],
  440. partialRightArgs = bindData[3],
  441. thisArg = bindData[4],
  442. arity = bindData[5];
  443. var isBind = bitmask & 1,
  444. isBindKey = bitmask & 2,
  445. isCurry = bitmask & 4,
  446. isCurryBound = bitmask & 8,
  447. key = func;
  448. function bound() {
  449. var thisBinding = isBind ? thisArg : this;
  450. if (partialArgs) {
  451. var args = partialArgs.slice();
  452. push.apply(args, arguments);
  453. }
  454. if (partialRightArgs || isCurry) {
  455. args || (args = slice(arguments));
  456. if (partialRightArgs) {
  457. push.apply(args, partialRightArgs);
  458. }
  459. if (isCurry && args.length < arity) {
  460. bitmask |= 16 & ~32;
  461. return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
  462. }
  463. }
  464. args || (args = arguments);
  465. if (isBindKey) {
  466. func = thisBinding[key];
  467. }
  468. if (this instanceof bound) {
  469. thisBinding = baseCreate(func.prototype);
  470. var result = func.apply(thisBinding, args);
  471. return isObject(result) ? result : thisBinding;
  472. }
  473. return func.apply(thisBinding, args);
  474. }
  475. return bound;
  476. }
  477. /**
  478. * The base implementation of `_.difference` that accepts a single array
  479. * of values to exclude.
  480. *
  481. * @private
  482. * @param {Array} array The array to process.
  483. * @param {Array} [values] The array of values to exclude.
  484. * @returns {Array} Returns a new array of filtered values.
  485. */
  486. function baseDifference(array, values) {
  487. var index = -1,
  488. indexOf = getIndexOf(),
  489. length = array ? array.length : 0,
  490. result = [];
  491. while (++index < length) {
  492. var value = array[index];
  493. if (indexOf(values, value) < 0) {
  494. result.push(value);
  495. }
  496. }
  497. return result;
  498. }
  499. /**
  500. * The base implementation of `_.flatten` without support for callback
  501. * shorthands or `thisArg` binding.
  502. *
  503. * @private
  504. * @param {Array} array The array to flatten.
  505. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  506. * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
  507. * @param {number} [fromIndex=0] The index to start from.
  508. * @returns {Array} Returns a new flattened array.
  509. */
  510. function baseFlatten(array, isShallow, isStrict, fromIndex) {
  511. var index = (fromIndex || 0) - 1,
  512. length = array ? array.length : 0,
  513. result = [];
  514. while (++index < length) {
  515. var value = array[index];
  516. if (value && typeof value == 'object' && typeof value.length == 'number'
  517. && (isArray(value) || isArguments(value))) {
  518. // recursively flatten arrays (susceptible to call stack limits)
  519. if (!isShallow) {
  520. value = baseFlatten(value, isShallow, isStrict);
  521. }
  522. var valIndex = -1,
  523. valLength = value.length,
  524. resIndex = result.length;
  525. result.length += valLength;
  526. while (++valIndex < valLength) {
  527. result[resIndex++] = value[valIndex];
  528. }
  529. } else if (!isStrict) {
  530. result.push(value);
  531. }
  532. }
  533. return result;
  534. }
  535. /**
  536. * The base implementation of `_.isEqual`, without support for `thisArg` binding,
  537. * that allows partial "_.where" style comparisons.
  538. *
  539. * @private
  540. * @param {*} a The value to compare.
  541. * @param {*} b The other value to compare.
  542. * @param {Function} [callback] The function to customize comparing values.
  543. * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
  544. * @param {Array} [stackA=[]] Tracks traversed `a` objects.
  545. * @param {Array} [stackB=[]] Tracks traversed `b` objects.
  546. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  547. */
  548. function baseIsEqual(a, b, stackA, stackB) {
  549. if (a === b) {
  550. return a !== 0 || (1 / a == 1 / b);
  551. }
  552. var type = typeof a,
  553. otherType = typeof b;
  554. if (a === a &&
  555. !(a && objectTypes[type]) &&
  556. !(b && objectTypes[otherType])) {
  557. return false;
  558. }
  559. if (a == null || b == null) {
  560. return a === b;
  561. }
  562. var className = toString.call(a),
  563. otherClass = toString.call(b);
  564. if (className != otherClass) {
  565. return false;
  566. }
  567. switch (className) {
  568. case boolClass:
  569. case dateClass:
  570. return +a == +b;
  571. case numberClass:
  572. return a != +a
  573. ? b != +b
  574. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  575. case regexpClass:
  576. case stringClass:
  577. return a == String(b);
  578. }
  579. var isArr = className == arrayClass;
  580. if (!isArr) {
  581. var aWrapped = a instanceof lodash,
  582. bWrapped = b instanceof lodash;
  583. if (aWrapped || bWrapped) {
  584. return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, stackA, stackB);
  585. }
  586. if (className != objectClass) {
  587. return false;
  588. }
  589. var ctorA = a.constructor,
  590. ctorB = b.constructor;
  591. if (ctorA != ctorB &&
  592. !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
  593. ('constructor' in a && 'constructor' in b)
  594. ) {
  595. return false;
  596. }
  597. }
  598. stackA || (stackA = []);
  599. stackB || (stackB = []);
  600. var length = stackA.length;
  601. while (length--) {
  602. if (stackA[length] == a) {
  603. return stackB[length] == b;
  604. }
  605. }
  606. var result = true,
  607. size = 0;
  608. stackA.push(a);
  609. stackB.push(b);
  610. if (isArr) {
  611. size = b.length;
  612. result = size == a.length;
  613. if (result) {
  614. while (size--) {
  615. if (!(result = baseIsEqual(a[size], b[size], stackA, stackB))) {
  616. break;
  617. }
  618. }
  619. }
  620. return result;
  621. }
  622. forIn(b, function(value, key, b) {
  623. if (hasOwnProperty.call(b, key)) {
  624. size++;
  625. return !(result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, stackA, stackB)) && indicatorObject;
  626. }
  627. });
  628. if (result) {
  629. forIn(a, function(value, key, a) {
  630. if (hasOwnProperty.call(a, key)) {
  631. return !(result = --size > -1) && indicatorObject;
  632. }
  633. });
  634. }
  635. return result;
  636. }
  637. /**
  638. * The base implementation of `_.random` without argument juggling or support
  639. * for returning floating-point numbers.
  640. *
  641. * @private
  642. * @param {number} min The minimum possible value.
  643. * @param {number} max The maximum possible value.
  644. * @returns {number} Returns a random number.
  645. */
  646. function baseRandom(min, max) {
  647. return min + floor(nativeRandom() * (max - min + 1));
  648. }
  649. /**
  650. * The base implementation of `_.uniq` without support for callback shorthands
  651. * or `thisArg` binding.
  652. *
  653. * @private
  654. * @param {Array} array The array to process.
  655. * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
  656. * @param {Function} [callback] The function called per iteration.
  657. * @returns {Array} Returns a duplicate-value-free array.
  658. */
  659. function baseUniq(array, isSorted, callback) {
  660. var index = -1,
  661. indexOf = getIndexOf(),
  662. length = array ? array.length : 0,
  663. result = [],
  664. seen = callback ? [] : result;
  665. while (++index < length) {
  666. var value = array[index],
  667. computed = callback ? callback(value, index, array) : value;
  668. if (isSorted
  669. ? !index || seen[seen.length - 1] !== computed
  670. : indexOf(seen, computed) < 0
  671. ) {
  672. if (callback) {
  673. seen.push(computed);
  674. }
  675. result.push(value);
  676. }
  677. }
  678. return result;
  679. }
  680. /**
  681. * Creates a function that aggregates a collection, creating an object composed
  682. * of keys generated from the results of running each element of the collection
  683. * through a callback. The given `setter` function sets the keys and values
  684. * of the composed object.
  685. *
  686. * @private
  687. * @param {Function} setter The setter function.
  688. * @returns {Function} Returns the new aggregator function.
  689. */
  690. function createAggregator(setter) {
  691. return function(collection, callback, thisArg) {
  692. var result = {};
  693. callback = createCallback(callback, thisArg, 3);
  694. var index = -1,
  695. length = collection ? collection.length : 0;
  696. if (typeof length == 'number') {
  697. while (++index < length) {
  698. var value = collection[index];
  699. setter(result, value, callback(value, index, collection), collection);
  700. }
  701. } else {
  702. forOwn(collection, function(value, key, collection) {
  703. setter(result, value, callback(value, key, collection), collection);
  704. });
  705. }
  706. return result;
  707. };
  708. }
  709. /**
  710. * Creates a function that, when called, either curries or invokes `func`
  711. * with an optional `this` binding and partially applied arguments.
  712. *
  713. * @private
  714. * @param {Function|string} func The function or method name to reference.
  715. * @param {number} bitmask The bitmask of method flags to compose.
  716. * The bitmask may be composed of the following flags:
  717. * 1 - `_.bind`
  718. * 2 - `_.bindKey`
  719. * 4 - `_.curry`
  720. * 8 - `_.curry` (bound)
  721. * 16 - `_.partial`
  722. * 32 - `_.partialRight`
  723. * @param {Array} [partialArgs] An array of arguments to prepend to those
  724. * provided to the new function.
  725. * @param {Array} [partialRightArgs] An array of arguments to append to those
  726. * provided to the new function.
  727. * @param {*} [thisArg] The `this` binding of `func`.
  728. * @param {number} [arity] The arity of `func`.
  729. * @returns {Function} Returns the new function.
  730. */
  731. function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
  732. var isBind = bitmask & 1,
  733. isBindKey = bitmask & 2,
  734. isCurry = bitmask & 4,
  735. isCurryBound = bitmask & 8,
  736. isPartial = bitmask & 16,
  737. isPartialRight = bitmask & 32;
  738. if (!isBindKey && !isFunction(func)) {
  739. throw new TypeError;
  740. }
  741. if (isPartial && !partialArgs.length) {
  742. bitmask &= ~16;
  743. isPartial = partialArgs = false;
  744. }
  745. if (isPartialRight && !partialRightArgs.length) {
  746. bitmask &= ~32;
  747. isPartialRight = partialRightArgs = false;
  748. }
  749. // fast path for `_.bind`
  750. var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
  751. return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
  752. }
  753. /**
  754. * Used by `escape` to convert characters to HTML entities.
  755. *
  756. * @private
  757. * @param {string} match The matched character to escape.
  758. * @returns {string} Returns the escaped character.
  759. */
  760. function escapeHtmlChar(match) {
  761. return htmlEscapes[match];
  762. }
  763. /**
  764. * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
  765. * customized, this method returns the custom method, otherwise it returns
  766. * the `baseIndexOf` function.
  767. *
  768. * @private
  769. * @returns {Function} Returns the "indexOf" function.
  770. */
  771. function getIndexOf() {
  772. var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
  773. return result;
  774. }
  775. /**
  776. * Used by `unescape` to convert HTML entities to characters.
  777. *
  778. * @private
  779. * @param {string} match The matched character to unescape.
  780. * @returns {string} Returns the unescaped character.
  781. */
  782. function unescapeHtmlChar(match) {
  783. return htmlUnescapes[match];
  784. }
  785. /*--------------------------------------------------------------------------*/
  786. /**
  787. * Checks if `value` is an `arguments` object.
  788. *
  789. * @static
  790. * @memberOf _
  791. * @category Objects
  792. * @param {*} value The value to check.
  793. * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
  794. * @example
  795. *
  796. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  797. * // => true
  798. *
  799. * _.isArguments([1, 2, 3]);
  800. * // => false
  801. */
  802. function isArguments(value) {
  803. return value && typeof value == 'object' && typeof value.length == 'number' &&
  804. toString.call(value) == argsClass || false;
  805. }
  806. // fallback for browsers that can't detect `arguments` objects by [[Class]]
  807. if (!isArguments(arguments)) {
  808. isArguments = function(value) {
  809. return value && typeof value == 'object' && typeof value.length == 'number' &&
  810. hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
  811. };
  812. }
  813. /**
  814. * Checks if `value` is an array.
  815. *
  816. * @static
  817. * @memberOf _
  818. * @type Function
  819. * @category Objects
  820. * @param {*} value The value to check.
  821. * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
  822. * @example
  823. *
  824. * (function() { return _.isArray(arguments); })();
  825. * // => false
  826. *
  827. * _.isArray([1, 2, 3]);
  828. * // => true
  829. */
  830. var isArray = nativeIsArray || function(value) {
  831. return value && typeof value == 'object' && typeof value.length == 'number' &&
  832. toString.call(value) == arrayClass || false;
  833. };
  834. /**
  835. * A fallback implementation of `Object.keys` which produces an array of the
  836. * given object's own enumerable property names.
  837. *
  838. * @private
  839. * @type Function
  840. * @param {Object} object The object to inspect.
  841. * @returns {Array} Returns an array of property names.
  842. */
  843. var shimKeys = function(object) {
  844. var index, iterable = object, result = [];
  845. if (!iterable) return result;
  846. if (!(objectTypes[typeof object])) return result;
  847. for (index in iterable) {
  848. if (hasOwnProperty.call(iterable, index)) {
  849. result.push(index);
  850. }
  851. }
  852. return result
  853. };
  854. /**
  855. * Creates an array composed of the own enumerable property names of an object.
  856. *
  857. * @static
  858. * @memberOf _
  859. * @category Objects
  860. * @param {Object} object The object to inspect.
  861. * @returns {Array} Returns an array of property names.
  862. * @example
  863. *
  864. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  865. * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
  866. */
  867. var keys = !nativeKeys ? shimKeys : function(object) {
  868. if (!isObject(object)) {
  869. return [];
  870. }
  871. return nativeKeys(object);
  872. };
  873. /**
  874. * Used to convert characters to HTML entities:
  875. *
  876. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  877. * don't require escaping in HTML and have no special meaning unless they're part
  878. * of a tag or an unquoted attribute value.
  879. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  880. */
  881. var htmlEscapes = {
  882. '&': '&amp;',
  883. '<': '&lt;',
  884. '>': '&gt;',
  885. '"': '&quot;',
  886. "'": '&#x27;'
  887. };
  888. /** Used to convert HTML entities to characters */
  889. var htmlUnescapes = invert(htmlEscapes);
  890. /** Used to match HTML entities and HTML characters */
  891. var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
  892. reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
  893. /*--------------------------------------------------------------------------*/
  894. /**
  895. * Assigns own enumerable properties of source object(s) to the destination
  896. * object. Subsequent sources will overwrite property assignments of previous
  897. * sources. If a callback is provided it will be executed to produce the
  898. * assigned values. The callback is bound to `thisArg` and invoked with two
  899. * arguments; (objectValue, sourceValue).
  900. *
  901. * @static
  902. * @memberOf _
  903. * @type Function
  904. * @alias extend
  905. * @category Objects
  906. * @param {Object} object The destination object.
  907. * @param {...Object} [source] The source objects.
  908. * @param {Function} [callback] The function to customize assigning values.
  909. * @param {*} [thisArg] The `this` binding of `callback`.
  910. * @returns {Object} Returns the destination object.
  911. * @example
  912. *
  913. * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
  914. * // => { 'name': 'fred', 'employer': 'slate' }
  915. *
  916. * var defaults = _.partialRight(_.assign, function(a, b) {
  917. * return typeof a == 'undefined' ? b : a;
  918. * });
  919. *
  920. * var object = { 'name': 'barney' };
  921. * defaults(object, { 'name': 'fred', 'employer': 'slate' });
  922. * // => { 'name': 'barney', 'employer': 'slate' }
  923. */
  924. function assign(object) {
  925. if (!object) {
  926. return object;
  927. }
  928. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  929. var iterable = arguments[argsIndex];
  930. if (iterable) {
  931. for (var key in iterable) {
  932. object[key] = iterable[key];
  933. }
  934. }
  935. }
  936. return object;
  937. }
  938. /**
  939. * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
  940. * be cloned, otherwise they will be assigned by reference. If a callback
  941. * is provided it will be executed to produce the cloned values. If the
  942. * callback returns `undefined` cloning will be handled by the method instead.
  943. * The callback is bound to `thisArg` and invoked with one argument; (value).
  944. *
  945. * @static
  946. * @memberOf _
  947. * @category Objects
  948. * @param {*} value The value to clone.
  949. * @param {boolean} [isDeep=false] Specify a deep clone.
  950. * @param {Function} [callback] The function to customize cloning values.
  951. * @param {*} [thisArg] The `this` binding of `callback`.
  952. * @returns {*} Returns the cloned value.
  953. * @example
  954. *
  955. * var characters = [
  956. * { 'name': 'barney', 'age': 36 },
  957. * { 'name': 'fred', 'age': 40 }
  958. * ];
  959. *
  960. * var shallow = _.clone(characters);
  961. * shallow[0] === characters[0];
  962. * // => true
  963. *
  964. * var deep = _.clone(characters, true);
  965. * deep[0] === characters[0];
  966. * // => false
  967. *
  968. * _.mixin({
  969. * 'clone': _.partialRight(_.clone, function(value) {
  970. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  971. * })
  972. * });
  973. *
  974. * var clone = _.clone(document.body);
  975. * clone.childNodes.length;
  976. * // => 0
  977. */
  978. function clone(value) {
  979. return isObject(value)
  980. ? (isArray(value) ? slice(value) : assign({}, value))
  981. : value;
  982. }
  983. /**
  984. * Assigns own enumerable properties of source object(s) to the destination
  985. * object for all destination properties that resolve to `undefined`. Once a
  986. * property is set, additional defaults of the same property will be ignored.
  987. *
  988. * @static
  989. * @memberOf _
  990. * @type Function
  991. * @category Objects
  992. * @param {Object} object The destination object.
  993. * @param {...Object} [source] The source objects.
  994. * @param- {Object} [guard] Allows working with `_.reduce` without using its
  995. * `key` and `object` arguments as sources.
  996. * @returns {Object} Returns the destination object.
  997. * @example
  998. *
  999. * var object = { 'name': 'barney' };
  1000. * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
  1001. * // => { 'name': 'barney', 'employer': 'slate' }
  1002. */
  1003. function defaults(object) {
  1004. if (!object) {
  1005. return object;
  1006. }
  1007. for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
  1008. var iterable = arguments[argsIndex];
  1009. if (iterable) {
  1010. for (var key in iterable) {
  1011. if (typeof object[key] == 'undefined') {
  1012. object[key] = iterable[key];
  1013. }
  1014. }
  1015. }
  1016. }
  1017. return object;
  1018. }
  1019. /**
  1020. * Iterates over own and inherited enumerable properties of an object,
  1021. * executing the callback for each property. The callback is bound to `thisArg`
  1022. * and invoked with three arguments; (value, key, object). Callbacks may exit
  1023. * iteration early by explicitly returning `false`.
  1024. *
  1025. * @static
  1026. * @memberOf _
  1027. * @type Function
  1028. * @category Objects
  1029. * @param {Object} object The object to iterate over.
  1030. * @param {Function} [callback=identity] The function called per iteration.
  1031. * @param {*} [thisArg] The `this` binding of `callback`.
  1032. * @returns {Object} Returns `object`.
  1033. * @example
  1034. *
  1035. * function Shape() {
  1036. * this.x = 0;
  1037. * this.y = 0;
  1038. * }
  1039. *
  1040. * Shape.prototype.move = function(x, y) {
  1041. * this.x += x;
  1042. * this.y += y;
  1043. * };
  1044. *
  1045. * _.forIn(new Shape, function(value, key) {
  1046. * console.log(key);
  1047. * });
  1048. * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
  1049. */
  1050. var forIn = function(collection, callback) {
  1051. var index, iterable = collection, result = iterable;
  1052. if (!iterable) return result;
  1053. if (!objectTypes[typeof iterable]) return result;
  1054. for (index in iterable) {
  1055. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  1056. }
  1057. return result
  1058. };
  1059. /**
  1060. * Iterates over own enumerable properties of an object, executing the callback
  1061. * for each property. The callback is bound to `thisArg` and invoked with three
  1062. * arguments; (value, key, object). Callbacks may exit iteration early by
  1063. * explicitly returning `false`.
  1064. *
  1065. * @static
  1066. * @memberOf _
  1067. * @type Function
  1068. * @category Objects
  1069. * @param {Object} object The object to iterate over.
  1070. * @param {Function} [callback=identity] The function called per iteration.
  1071. * @param {*} [thisArg] The `this` binding of `callback`.
  1072. * @returns {Object} Returns `object`.
  1073. * @example
  1074. *
  1075. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  1076. * console.log(key);
  1077. * });
  1078. * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
  1079. */
  1080. var forOwn = function(collection, callback) {
  1081. var index, iterable = collection, result = iterable;
  1082. if (!iterable) return result;
  1083. if (!objectTypes[typeof iterable]) return result;
  1084. for (index in iterable) {
  1085. if (hasOwnProperty.call(iterable, index)) {
  1086. if (callback(iterable[index], index, collection) === indicatorObject) return result;
  1087. }
  1088. }
  1089. return result
  1090. };
  1091. /**
  1092. * Creates a sorted array of property names of all enumerable properties,
  1093. * own and inherited, of `object` that have function values.
  1094. *
  1095. * @static
  1096. * @memberOf _
  1097. * @alias methods
  1098. * @category Objects
  1099. * @param {Object} object The object to inspect.
  1100. * @returns {Array} Returns an array of property names that have function values.
  1101. * @example
  1102. *
  1103. * _.functions(_);
  1104. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  1105. */
  1106. function functions(object) {
  1107. var result = [];
  1108. forIn(object, function(value, key) {
  1109. if (isFunction(value)) {
  1110. result.push(key);
  1111. }
  1112. });
  1113. return result.sort();
  1114. }
  1115. /**
  1116. * Checks if the specified object `property` exists and is a direct property,
  1117. * instead of an inherited property.
  1118. *
  1119. * @static
  1120. * @memberOf _
  1121. * @category Objects
  1122. * @param {Object} object The object to check.
  1123. * @param {string} property The property to check for.
  1124. * @returns {boolean} Returns `true` if key is a direct property, else `false`.
  1125. * @example
  1126. *
  1127. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  1128. * // => true
  1129. */
  1130. function has(object, property) {
  1131. return object ? hasOwnProperty.call(object, property) : false;
  1132. }
  1133. /**
  1134. * Creates an object composed of the inverted keys and values of the given object.
  1135. *
  1136. * @static
  1137. * @memberOf _
  1138. * @category Objects
  1139. * @param {Object} object The object to invert.
  1140. * @returns {Object} Returns the created inverted object.
  1141. * @example
  1142. *
  1143. * _.invert({ 'first': 'fred', 'second': 'barney' });
  1144. * // => { 'fred': 'first', 'barney': 'second' }
  1145. */
  1146. function invert(object) {
  1147. var index = -1,
  1148. props = keys(object),
  1149. length = props.length,
  1150. result = {};
  1151. while (++index < length) {
  1152. var key = props[index];
  1153. result[object[key]] = key;
  1154. }
  1155. return result;
  1156. }
  1157. /**
  1158. * Checks if `value` is a boolean value.
  1159. *
  1160. * @static
  1161. * @memberOf _
  1162. * @category Objects
  1163. * @param {*} value The value to check.
  1164. * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
  1165. * @example
  1166. *
  1167. * _.isBoolean(null);
  1168. * // => false
  1169. */
  1170. function isBoolean(value) {
  1171. return value === true || value === false ||
  1172. value && typeof value == 'object' && toString.call(value) == boolClass || false;
  1173. }
  1174. /**
  1175. * Checks if `value` is a date.
  1176. *
  1177. * @static
  1178. * @memberOf _
  1179. * @category Objects
  1180. * @param {*} value The value to check.
  1181. * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
  1182. * @example
  1183. *
  1184. * _.isDate(new Date);
  1185. * // => true
  1186. */
  1187. function isDate(value) {
  1188. return value && typeof value == 'object' && toString.call(value) == dateClass || false;
  1189. }
  1190. /**
  1191. * Checks if `value` is a DOM element.
  1192. *
  1193. * @static
  1194. * @memberOf _
  1195. * @category Objects
  1196. * @param {*} value The value to check.
  1197. * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
  1198. * @example
  1199. *
  1200. * _.isElement(document.body);
  1201. * // => true
  1202. */
  1203. function isElement(value) {
  1204. return value && value.nodeType === 1 || false;
  1205. }
  1206. /**
  1207. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  1208. * length of `0` and objects with no own enumerable properties are considered
  1209. * "empty".
  1210. *
  1211. * @static
  1212. * @memberOf _
  1213. * @category Objects
  1214. * @param {Array|Object|string} value The value to inspect.
  1215. * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
  1216. * @example
  1217. *
  1218. * _.isEmpty([1, 2, 3]);
  1219. * // => false
  1220. *
  1221. * _.isEmpty({});
  1222. * // => true
  1223. *
  1224. * _.isEmpty('');
  1225. * // => true
  1226. */
  1227. function isEmpty(value) {
  1228. if (!value) {
  1229. return true;
  1230. }
  1231. if (isArray(value) || isString(value)) {
  1232. return !value.length;
  1233. }
  1234. for (var key in value) {
  1235. if (hasOwnProperty.call(value, key)) {
  1236. return false;
  1237. }
  1238. }
  1239. return true;
  1240. }
  1241. /**
  1242. * Performs a deep comparison between two values to determine if they are
  1243. * equivalent to each other. If a callback is provided it will be executed
  1244. * to compare values. If the callback returns `undefined` comparisons will
  1245. * be handled by the method instead. The callback is bound to `thisArg` and
  1246. * invoked with two arguments; (a, b).
  1247. *
  1248. * @static
  1249. * @memberOf _
  1250. * @category Objects
  1251. * @param {*} a The value to compare.
  1252. * @param {*} b The other value to compare.
  1253. * @param {Function} [callback] The function to customize comparing values.
  1254. * @param {*} [thisArg] The `this` binding of `callback`.
  1255. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  1256. * @example
  1257. *
  1258. * var object = { 'name': 'fred' };
  1259. * var copy = { 'name': 'fred' };
  1260. *
  1261. * object == copy;
  1262. * // => false
  1263. *
  1264. * _.isEqual(object, copy);
  1265. * // => true
  1266. *
  1267. * var words = ['hello', 'goodbye'];
  1268. * var otherWords = ['hi', 'goodbye'];
  1269. *
  1270. * _.isEqual(words, otherWords, function(a, b) {
  1271. * var reGreet = /^(?:hello|hi)$/i,
  1272. * aGreet = _.isString(a) && reGreet.test(a),
  1273. * bGreet = _.isString(b) && reGreet.test(b);
  1274. *
  1275. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  1276. * });
  1277. * // => true
  1278. */
  1279. function isEqual(a, b) {
  1280. return baseIsEqual(a, b);
  1281. }
  1282. /**
  1283. * Checks if `value` is, or can be coerced to, a finite number.
  1284. *
  1285. * Note: This is not the same as native `isFinite` which will return true for
  1286. * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
  1287. *
  1288. * @static
  1289. * @memberOf _
  1290. * @category Objects
  1291. * @param {*} value The value to check.
  1292. * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
  1293. * @example
  1294. *
  1295. * _.isFinite(-101);
  1296. * // => true
  1297. *
  1298. * _.isFinite('10');
  1299. * // => true
  1300. *
  1301. * _.isFinite(true);
  1302. * // => false
  1303. *
  1304. * _.isFinite('');
  1305. * // => false
  1306. *
  1307. * _.isFinite(Infinity);
  1308. * // => false
  1309. */
  1310. function isFinite(value) {
  1311. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  1312. }
  1313. /**
  1314. * Checks if `value` is a function.
  1315. *
  1316. * @static
  1317. * @memberOf _
  1318. * @category Objects
  1319. * @param {*} value The value to check.
  1320. * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
  1321. * @example
  1322. *
  1323. * _.isFunction(_);
  1324. * // => true
  1325. */
  1326. function isFunction(value) {
  1327. return typeof value == 'function';
  1328. }
  1329. // fallback for older versions of Chrome and Safari
  1330. if (isFunction(/x/)) {
  1331. isFunction = function(value) {
  1332. return typeof value == 'function' && toString.call(value) == funcClass;
  1333. };
  1334. }
  1335. /**
  1336. * Checks if `value` is the language type of Object.
  1337. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1338. *
  1339. * @static
  1340. * @memberOf _
  1341. * @category Objects
  1342. * @param {*} value The value to check.
  1343. * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
  1344. * @example
  1345. *
  1346. * _.isObject({});
  1347. * // => true
  1348. *
  1349. * _.isObject([1, 2, 3]);
  1350. * // => true
  1351. *
  1352. * _.isObject(1);
  1353. * // => false
  1354. */
  1355. function isObject(value) {
  1356. // check if the value is the ECMAScript language type of Object
  1357. // http://es5.github.io/#x8
  1358. // and avoid a V8 bug
  1359. // http://code.google.com/p/v8/issues/detail?id=2291
  1360. return !!(value && objectTypes[typeof value]);
  1361. }
  1362. /**
  1363. * Checks if `value` is `NaN`.
  1364. *
  1365. * Note: This is not the same as native `isNaN` which will return `true` for
  1366. * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
  1367. *
  1368. * @static
  1369. * @memberOf _
  1370. * @category Objects
  1371. * @param {*} value The value to check.
  1372. * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
  1373. * @example
  1374. *
  1375. * _.isNaN(NaN);
  1376. * // => true
  1377. *
  1378. * _.isNaN(new Number(NaN));
  1379. * // => true
  1380. *
  1381. * isNaN(undefined);
  1382. * // => true
  1383. *
  1384. * _.isNaN(undefined);
  1385. * // => false
  1386. */
  1387. function isNaN(value) {
  1388. // `NaN` as a primitive is the only value that is not equal to itself
  1389. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  1390. return isNumber(value) && value != +value;
  1391. }
  1392. /**
  1393. * Checks if `value` is `null`.
  1394. *
  1395. * @static
  1396. * @memberOf _
  1397. * @category Objects
  1398. * @param {*} value The value to check.
  1399. * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
  1400. * @example
  1401. *
  1402. * _.isNull(null);
  1403. * // => true
  1404. *
  1405. * _.isNull(undefined);
  1406. * // => false
  1407. */
  1408. function isNull(value) {
  1409. return value === null;
  1410. }
  1411. /**
  1412. * Checks if `value` is a number.
  1413. *
  1414. * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
  1415. *
  1416. * @static
  1417. * @memberOf _
  1418. * @category Objects
  1419. * @param {*} value The value to check.
  1420. * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
  1421. * @example
  1422. *
  1423. * _.isNumber(8.4 * 5);
  1424. * // => true
  1425. */
  1426. function isNumber(value) {
  1427. return typeof value == 'number' ||
  1428. value && typeof value == 'object' && toString.call(value) == numberClass || false;
  1429. }
  1430. /**
  1431. * Checks if `value` is a regular expression.
  1432. *
  1433. * @static
  1434. * @memberOf _
  1435. * @category Objects
  1436. * @param {*} value The value to check.
  1437. * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
  1438. * @example
  1439. *
  1440. * _.isRegExp(/fred/);
  1441. * // => true
  1442. */
  1443. function isRegExp(value) {
  1444. return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
  1445. }
  1446. /**
  1447. * Checks if `value` is a string.
  1448. *
  1449. * @static
  1450. * @memberOf _
  1451. * @category Objects
  1452. * @param {*} value The value to check.
  1453. * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
  1454. * @example
  1455. *
  1456. * _.isString('fred');
  1457. * // => true
  1458. */
  1459. function isString(value) {
  1460. return typeof value == 'string' ||
  1461. value && typeof value == 'object' && toString.call(value) == stringClass || false;
  1462. }
  1463. /**
  1464. * Checks if `value` is `undefined`.
  1465. *
  1466. * @static
  1467. * @memberOf _
  1468. * @category Objects
  1469. * @param {*} value The value to check.
  1470. * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
  1471. * @example
  1472. *
  1473. * _.isUndefined(void 0);
  1474. * // => true
  1475. */
  1476. function isUndefined(value) {
  1477. return typeof value == 'undefined';
  1478. }
  1479. /**
  1480. * Creates a shallow clone of `object` excluding the specified properties.
  1481. * Property names may be specified as individual arguments or as arrays of
  1482. * property names. If a callback is provided it will be executed for each
  1483. * property of `object` omitting the properties the callback returns truey
  1484. * for. The callback is bound to `thisArg` and invoked with three arguments;
  1485. * (value, key, object).
  1486. *
  1487. * @static
  1488. * @memberOf _
  1489. * @category Objects
  1490. * @param {Object} object The source object.
  1491. * @param {Function|...string|string[]} [callback] The properties to omit or the
  1492. * function called per iteration.
  1493. * @param {*} [thisArg] The `this` binding of `callback`.
  1494. * @returns {Object} Returns an object without the omitted properties.
  1495. * @example
  1496. *
  1497. * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
  1498. * // => { 'name': 'fred' }
  1499. *
  1500. * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
  1501. * return typeof value == 'number';
  1502. * });
  1503. * // => { 'name': 'fred' }
  1504. */
  1505. function omit(object) {
  1506. var props = [];
  1507. forIn(object, function(value, key) {
  1508. props.push(key);
  1509. });
  1510. props = baseDifference(props, baseFlatten(arguments, true, false, 1));
  1511. var index = -1,
  1512. length = props.length,
  1513. result = {};
  1514. while (++index < length) {
  1515. var key = props[index];
  1516. result[key] = object[key];
  1517. }
  1518. return result;
  1519. }
  1520. /**
  1521. * Creates a two dimensional array of an object's key-value pairs,
  1522. * i.e. `[[key1, value1], [key2, value2]]`.
  1523. *
  1524. * @static
  1525. * @memberOf _
  1526. * @category Objects
  1527. * @param {Object} object The object to inspect.
  1528. * @returns {Array} Returns new array of key-value pairs.
  1529. * @example
  1530. *
  1531. * _.pairs({ 'barney': 36, 'fred': 40 });
  1532. * // => [['barney', 3