PageRenderTime 74ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/files/cascadeframework/1.0/js/lib/lodash/lodash.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1515 lines | 1150 code | 42 blank | 323 comment | 91 complexity | f248cf90f37e8cd3646e905bcbf41584 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 1.0.0 <http://lodash.com/>
  4. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  5. * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
  6. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  7. * Available under MIT license <http://lodash.com/license>
  8. */
  9. ;(function(window, undefined) {
  10. /** Detect free variable `exports` */
  11. var freeExports = typeof exports == 'object' && exports;
  12. /** Detect free variable `global` and use it as `window` */
  13. var freeGlobal = typeof global == 'object' && global;
  14. if (freeGlobal.global === freeGlobal) {
  15. window = freeGlobal;
  16. }
  17. /** Used for array and object method references */
  18. var arrayRef = [],
  19. objectRef = {};
  20. /** Used to generate unique IDs */
  21. var idCounter = 0;
  22. /** Used internally to indicate various things */
  23. var indicatorObject = objectRef;
  24. /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */
  25. var largeArraySize = 30;
  26. /** Used to restore the original `_` reference in `noConflict` */
  27. var oldDash = window._;
  28. /** Used to match HTML entities */
  29. var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
  30. /** Used to match empty string literals in compiled template source */
  31. var reEmptyStringLeading = /\b__p \+= '';/g,
  32. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  33. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  34. /** Used to match regexp flags from their coerced string values */
  35. var reFlags = /\w*$/;
  36. /** Used to detect if a method is native */
  37. var reNative = RegExp('^' +
  38. (objectRef.valueOf + '')
  39. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  40. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  41. );
  42. /**
  43. * Used to match ES6 template delimiters
  44. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  45. */
  46. var reEsTemplate = /\$\{((?:(?=\\?)\\?[\s\S])*?)\}/g;
  47. /** Used to match "interpolate" template delimiters */
  48. var reInterpolate = /<%=([\s\S]+?)%>/g;
  49. /** Used to ensure capturing order of template delimiters */
  50. var reNoMatch = /($^)/;
  51. /** Used to match HTML characters */
  52. var reUnescapedHtml = /[&<>"']/g;
  53. /** Used to match unescaped characters in compiled string literals */
  54. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  55. /** Used to fix the JScript [[DontEnum]] bug */
  56. var shadowed = [
  57. 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
  58. 'toLocaleString', 'toString', 'valueOf'
  59. ];
  60. /** Used to make template sourceURLs easier to identify */
  61. var templateCounter = 0;
  62. /** Native method shortcuts */
  63. var ceil = Math.ceil,
  64. concat = arrayRef.concat,
  65. floor = Math.floor,
  66. getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  67. hasOwnProperty = objectRef.hasOwnProperty,
  68. push = arrayRef.push,
  69. toString = objectRef.toString;
  70. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  71. var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
  72. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  73. nativeIsFinite = window.isFinite,
  74. nativeIsNaN = window.isNaN,
  75. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  76. nativeMax = Math.max,
  77. nativeMin = Math.min,
  78. nativeRandom = Math.random;
  79. /** `Object#toString` result shortcuts */
  80. var argsClass = '[object Arguments]',
  81. arrayClass = '[object Array]',
  82. boolClass = '[object Boolean]',
  83. dateClass = '[object Date]',
  84. funcClass = '[object Function]',
  85. numberClass = '[object Number]',
  86. objectClass = '[object Object]',
  87. regexpClass = '[object RegExp]',
  88. stringClass = '[object String]';
  89. /** Detect various environments */
  90. var isIeOpera = !!window.attachEvent,
  91. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  92. /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */
  93. var isBindFast = nativeBind && !isV8;
  94. /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
  95. var isKeysFast = nativeKeys && (isIeOpera || isV8);
  96. /**
  97. * Detect the JScript [[DontEnum]] bug:
  98. *
  99. * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
  100. * made non-enumerable as well.
  101. */
  102. var hasDontEnumBug;
  103. /**
  104. * Detect if a `prototype` properties are enumerable by default:
  105. *
  106. * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
  107. * (if the prototype or a property on the prototype has been set)
  108. * incorrectly sets a function's `prototype` property [[Enumerable]]
  109. * value to `true`.
  110. */
  111. var hasEnumPrototype;
  112. /** Detect if own properties are iterated after inherited properties (IE < 9) */
  113. var iteratesOwnLast;
  114. /**
  115. * Detect if `Array#shift` and `Array#splice` augment array-like objects
  116. * incorrectly:
  117. *
  118. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  119. * and `splice()` functions that fail to remove the last element, `value[0]`,
  120. * of array-like objects even though the `length` property is set to `0`.
  121. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  122. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  123. */
  124. var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 },
  125. arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]);
  126. /** Detect if `arguments` object indexes are non-enumerable (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1) */
  127. var nonEnumArgs = true;
  128. (function() {
  129. var props = [];
  130. function ctor() { this.x = 1; }
  131. ctor.prototype = { 'valueOf': 1, 'y': 1 };
  132. for (var prop in new ctor) { props.push(prop); }
  133. for (prop in arguments) { nonEnumArgs = !prop; }
  134. hasDontEnumBug = !/valueOf/.test(props);
  135. hasEnumPrototype = ctor.propertyIsEnumerable('prototype');
  136. iteratesOwnLast = props[0] != 'x';
  137. }(1));
  138. /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */
  139. var argsAreObjects = arguments.constructor == Object;
  140. /** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */
  141. var noArgsClass = !isArguments(arguments);
  142. /**
  143. * Detect lack of support for accessing string characters by index:
  144. *
  145. * IE < 8 can't access characters by index and IE 8 can only access
  146. * characters by index on string literals.
  147. */
  148. var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx';
  149. /**
  150. * Detect if a node's [[Class]] is unresolvable (IE < 9)
  151. * and that the JS engine won't error when attempting to coerce an object to
  152. * a string without a `toString` function.
  153. */
  154. try {
  155. var noNodeClass = toString.call(document) == objectClass && !({ 'toString': 0 } + '');
  156. } catch(e) { }
  157. /** Used to identify object classifications that `_.clone` supports */
  158. var cloneableClasses = {};
  159. cloneableClasses[funcClass] = false;
  160. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  161. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  162. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  163. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  164. /** Used to lookup a built-in constructor by [[Class]] */
  165. var ctorByClass = {};
  166. ctorByClass[arrayClass] = Array;
  167. ctorByClass[boolClass] = Boolean;
  168. ctorByClass[dateClass] = Date;
  169. ctorByClass[objectClass] = Object;
  170. ctorByClass[numberClass] = Number;
  171. ctorByClass[regexpClass] = RegExp;
  172. ctorByClass[stringClass] = String;
  173. /** Used to determine if values are of the language type Object */
  174. var objectTypes = {
  175. 'boolean': false,
  176. 'function': true,
  177. 'object': true,
  178. 'number': false,
  179. 'string': false,
  180. 'undefined': false
  181. };
  182. /** Used to escape characters for inclusion in compiled string literals */
  183. var stringEscapes = {
  184. '\\': '\\',
  185. "'": "'",
  186. '\n': 'n',
  187. '\r': 'r',
  188. '\t': 't',
  189. '\u2028': 'u2028',
  190. '\u2029': 'u2029'
  191. };
  192. /*--------------------------------------------------------------------------*/
  193. /**
  194. * Creates a `lodash` object, that wraps the given `value`, to enable method
  195. * chaining.
  196. *
  197. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  198. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  199. * and `unshift`
  200. *
  201. * The chainable wrapper functions are:
  202. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`,
  203. * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`,
  204. * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`,
  205. * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`,
  206. * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
  207. * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`,
  208. * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`,
  209. * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip`
  210. *
  211. * The non-chainable wrapper functions are:
  212. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`,
  213. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`,
  214. * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`,
  215. * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`,
  216. * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`,
  217. * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId`
  218. *
  219. * The wrapper functions `first` and `last` return wrapped values when `n` is
  220. * passed, otherwise they return unwrapped values.
  221. *
  222. * @name _
  223. * @constructor
  224. * @category Chaining
  225. * @param {Mixed} value The value to wrap in a `lodash` instance.
  226. * @returns {Object} Returns a `lodash` instance.
  227. */
  228. function lodash(value) {
  229. // exit early if already wrapped, even if wrapped by a different `lodash` constructor
  230. if (value && typeof value == 'object' && value.__wrapped__) {
  231. return value;
  232. }
  233. // allow invoking `lodash` without the `new` operator
  234. if (!(this instanceof lodash)) {
  235. return new lodash(value);
  236. }
  237. this.__wrapped__ = value;
  238. }
  239. /**
  240. * By default, the template delimiters used by Lo-Dash are similar to those in
  241. * embedded Ruby (ERB). Change the following template settings to use alternative
  242. * delimiters.
  243. *
  244. * @static
  245. * @memberOf _
  246. * @type Object
  247. */
  248. lodash.templateSettings = {
  249. /**
  250. * Used to detect `data` property values to be HTML-escaped.
  251. *
  252. * @memberOf _.templateSettings
  253. * @type RegExp
  254. */
  255. 'escape': /<%-([\s\S]+?)%>/g,
  256. /**
  257. * Used to detect code to be evaluated.
  258. *
  259. * @memberOf _.templateSettings
  260. * @type RegExp
  261. */
  262. 'evaluate': /<%([\s\S]+?)%>/g,
  263. /**
  264. * Used to detect `data` property values to inject.
  265. *
  266. * @memberOf _.templateSettings
  267. * @type RegExp
  268. */
  269. 'interpolate': reInterpolate,
  270. /**
  271. * Used to reference the data object in the template text.
  272. *
  273. * @memberOf _.templateSettings
  274. * @type String
  275. */
  276. 'variable': '',
  277. /**
  278. * Used to import variables into the compiled template.
  279. *
  280. * @memberOf _.templateSettings
  281. * @type Object
  282. */
  283. 'imports': {
  284. /**
  285. * A reference to the `lodash` function.
  286. *
  287. * @memberOf _.templateSettings.imports
  288. * @type Function
  289. */
  290. '_': lodash
  291. }
  292. };
  293. /*--------------------------------------------------------------------------*/
  294. /**
  295. * The template used to create iterator functions.
  296. *
  297. * @private
  298. * @param {Obect} data The data object used to populate the text.
  299. * @returns {String} Returns the interpolated text.
  300. */
  301. var iteratorTemplate = template(
  302. // the `iterable` may be reassigned by the `top` snippet
  303. 'var index, iterable = <%= firstArg %>, ' +
  304. // assign the `result` variable an initial value
  305. 'result = iterable;\n' +
  306. // exit early if the first argument is falsey
  307. 'if (!iterable) return result;\n' +
  308. // add code before the iteration branches
  309. '<%= top %>;\n' +
  310. // array-like iteration:
  311. '<% if (arrays) { %>' +
  312. 'var length = iterable.length; index = -1;\n' +
  313. 'if (<%= arrays %>) {' +
  314. // add support for accessing string characters by index if needed
  315. ' <% if (noCharByIndex) { %>\n' +
  316. ' if (isString(iterable)) {\n' +
  317. " iterable = iterable.split('')\n" +
  318. ' }' +
  319. ' <% } %>\n' +
  320. // iterate over the array-like value
  321. ' while (++index < length) {\n' +
  322. ' <%= loop %>\n' +
  323. ' }\n' +
  324. '}\n' +
  325. 'else {' +
  326. // object iteration:
  327. // add support for iterating over `arguments` objects if needed
  328. ' <% } else if (nonEnumArgs) { %>\n' +
  329. ' var length = iterable.length; index = -1;\n' +
  330. ' if (length && isArguments(iterable)) {\n' +
  331. ' while (++index < length) {\n' +
  332. " index += '';\n" +
  333. ' <%= loop %>\n' +
  334. ' }\n' +
  335. ' } else {' +
  336. ' <% } %>' +
  337. // avoid iterating over `prototype` properties in older Firefox, Opera, and Safari
  338. ' <% if (hasEnumPrototype) { %>\n' +
  339. " var skipProto = typeof iterable == 'function';\n" +
  340. ' <% } %>' +
  341. // iterate own properties using `Object.keys` if it's fast
  342. ' <% if (isKeysFast && useHas) { %>\n' +
  343. ' var ownIndex = -1,\n' +
  344. ' ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n' +
  345. ' length = ownProps.length;\n\n' +
  346. ' while (++ownIndex < length) {\n' +
  347. ' index = ownProps[ownIndex];\n' +
  348. " <% if (hasEnumPrototype) { %>if (!(skipProto && index == 'prototype')) {\n <% } %>" +
  349. ' <%= loop %>\n' +
  350. ' <% if (hasEnumPrototype) { %>}\n<% } %>' +
  351. ' }' +
  352. // else using a for-in loop
  353. ' <% } else { %>\n' +
  354. ' for (index in iterable) {<%' +
  355. ' if (hasEnumPrototype || useHas) { %>\n if (<%' +
  356. " if (hasEnumPrototype) { %>!(skipProto && index == 'prototype')<% }" +
  357. ' if (hasEnumPrototype && useHas) { %> && <% }' +
  358. ' if (useHas) { %>hasOwnProperty.call(iterable, index)<% }' +
  359. ' %>) {' +
  360. ' <% } %>\n' +
  361. ' <%= loop %>;' +
  362. ' <% if (hasEnumPrototype || useHas) { %>\n }<% } %>\n' +
  363. ' }' +
  364. ' <% } %>' +
  365. // Because IE < 9 can't set the `[[Enumerable]]` attribute of an
  366. // existing property and the `constructor` property of a prototype
  367. // defaults to non-enumerable, Lo-Dash skips the `constructor`
  368. // property when it infers it's iterating over a `prototype` object.
  369. ' <% if (hasDontEnumBug) { %>\n\n' +
  370. ' var ctor = iterable.constructor;\n' +
  371. ' <% for (var k = 0; k < 7; k++) { %>\n' +
  372. " index = '<%= shadowed[k] %>';\n" +
  373. ' if (<%' +
  374. " if (shadowed[k] == 'constructor') {" +
  375. ' %>!(ctor && ctor.prototype === iterable) && <%' +
  376. ' } %>hasOwnProperty.call(iterable, index)) {\n' +
  377. ' <%= loop %>\n' +
  378. ' }' +
  379. ' <% } %>' +
  380. ' <% } %>' +
  381. ' <% if (arrays || nonEnumArgs) { %>\n}<% } %>\n' +
  382. // add code to the bottom of the iteration function
  383. '<%= bottom %>;\n' +
  384. // finally, return the `result`
  385. 'return result'
  386. );
  387. /** Reusable iterator options for `assign` and `defaults` */
  388. var defaultsIteratorOptions = {
  389. 'args': 'object, source, guard',
  390. 'top':
  391. 'var args = arguments,\n' +
  392. ' argsIndex = 0,\n' +
  393. " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
  394. 'while (++argsIndex < argsLength) {\n' +
  395. ' iterable = args[argsIndex];\n' +
  396. ' if (iterable && objectTypes[typeof iterable]) {',
  397. 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
  398. 'bottom': ' }\n}'
  399. };
  400. /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
  401. var eachIteratorOptions = {
  402. 'args': 'collection, callback, thisArg',
  403. 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)",
  404. 'arrays': "typeof length == 'number'",
  405. 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
  406. };
  407. /** Reusable iterator options for `forIn` and `forOwn` */
  408. var forOwnIteratorOptions = {
  409. 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
  410. 'arrays': false
  411. };
  412. /*--------------------------------------------------------------------------*/
  413. /**
  414. * Creates a function optimized to search large arrays for a given `value`,
  415. * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
  416. *
  417. * @private
  418. * @param {Array} array The array to search.
  419. * @param {Mixed} value The value to search for.
  420. * @param {Number} [fromIndex=0] The index to search from.
  421. * @param {Number} [largeSize=30] The length at which an array is considered large.
  422. * @returns {Boolean} Returns `true`, if `value` is found, else `false`.
  423. */
  424. function cachedContains(array, fromIndex, largeSize) {
  425. fromIndex || (fromIndex = 0);
  426. var length = array.length,
  427. isLarge = (length - fromIndex) >= (largeSize || largeArraySize);
  428. if (isLarge) {
  429. var cache = {},
  430. index = fromIndex - 1;
  431. while (++index < length) {
  432. // manually coerce `value` to a string because `hasOwnProperty`, in some
  433. // older versions of Firefox, coerces objects incorrectly
  434. var key = array[index] + '';
  435. (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
  436. }
  437. }
  438. return function(value) {
  439. if (isLarge) {
  440. var key = value + '';
  441. return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
  442. }
  443. return indexOf(array, value, fromIndex) > -1;
  444. }
  445. }
  446. /**
  447. * Used by `_.max` and `_.min` as the default `callback` when a given
  448. * `collection` is a string value.
  449. *
  450. * @private
  451. * @param {String} value The character to inspect.
  452. * @returns {Number} Returns the code unit of given character.
  453. */
  454. function charAtCallback(value) {
  455. return value.charCodeAt(0);
  456. }
  457. /**
  458. * Used by `sortBy` to compare transformed `collection` values, stable sorting
  459. * them in ascending order.
  460. *
  461. * @private
  462. * @param {Object} a The object to compare to `b`.
  463. * @param {Object} b The object to compare to `a`.
  464. * @returns {Number} Returns the sort order indicator of `1` or `-1`.
  465. */
  466. function compareAscending(a, b) {
  467. var ai = a.index,
  468. bi = b.index;
  469. a = a.criteria;
  470. b = b.criteria;
  471. // ensure a stable sort in V8 and other engines
  472. // http://code.google.com/p/v8/issues/detail?id=90
  473. if (a !== b) {
  474. if (a > b || typeof a == 'undefined') {
  475. return 1;
  476. }
  477. if (a < b || typeof b == 'undefined') {
  478. return -1;
  479. }
  480. }
  481. return ai < bi ? -1 : 1;
  482. }
  483. /**
  484. * Creates a function that, when called, invokes `func` with the `this` binding
  485. * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
  486. * bound function.
  487. *
  488. * @private
  489. * @param {Function|String} func The function to bind or the method name.
  490. * @param {Mixed} [thisArg] The `this` binding of `func`.
  491. * @param {Array} partialArgs An array of arguments to be partially applied.
  492. * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right.
  493. * @returns {Function} Returns the new bound function.
  494. */
  495. function createBound(func, thisArg, partialArgs, rightIndicator) {
  496. var isFunc = isFunction(func),
  497. isPartial = !partialArgs,
  498. key = thisArg;
  499. // juggle arguments
  500. if (isPartial) {
  501. partialArgs = thisArg;
  502. }
  503. if (!isFunc) {
  504. thisArg = func;
  505. }
  506. function bound() {
  507. // `Function#bind` spec
  508. // http://es5.github.com/#x15.3.4.5
  509. var args = arguments,
  510. thisBinding = isPartial ? this : thisArg;
  511. if (!isFunc) {
  512. func = thisArg[key];
  513. }
  514. if (partialArgs.length) {
  515. args = args.length
  516. ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
  517. : partialArgs;
  518. }
  519. if (this instanceof bound) {
  520. // ensure `new bound` is an instance of `bound` and `func`
  521. noop.prototype = func.prototype;
  522. thisBinding = new noop;
  523. noop.prototype = null;
  524. // mimic the constructor's `return` behavior
  525. // http://es5.github.com/#x13.2.2
  526. var result = func.apply(thisBinding, args);
  527. return isObject(result) ? result : thisBinding;
  528. }
  529. return func.apply(thisBinding, args);
  530. }
  531. return bound;
  532. }
  533. /**
  534. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  535. * name, the created callback will return the property value for a given element.
  536. * If `func` is an object, the created callback will return `true` for elements
  537. * that contain the equivalent object properties, otherwise it will return `false`.
  538. *
  539. * @private
  540. * @param {Mixed} [func=identity] The value to convert to a callback.
  541. * @param {Mixed} [thisArg] The `this` binding of the created callback.
  542. * @param {Number} [argCount=3] The number of arguments the callback accepts.
  543. * @returns {Function} Returns a callback function.
  544. */
  545. function createCallback(func, thisArg, argCount) {
  546. if (func == null) {
  547. return identity;
  548. }
  549. var type = typeof func;
  550. if (type != 'function') {
  551. if (type != 'object') {
  552. return function(object) {
  553. return object[func];
  554. };
  555. }
  556. var props = keys(func);
  557. return function(object) {
  558. var length = props.length,
  559. result = false;
  560. while (length--) {
  561. if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) {
  562. break;
  563. }
  564. }
  565. return result;
  566. };
  567. }
  568. if (typeof thisArg != 'undefined') {
  569. if (argCount === 1) {
  570. return function(value) {
  571. return func.call(thisArg, value);
  572. };
  573. }
  574. if (argCount === 2) {
  575. return function(a, b) {
  576. return func.call(thisArg, a, b);
  577. };
  578. }
  579. if (argCount === 4) {
  580. return function(accumulator, value, index, object) {
  581. return func.call(thisArg, accumulator, value, index, object);
  582. };
  583. }
  584. return function(value, index, object) {
  585. return func.call(thisArg, value, index, object);
  586. };
  587. }
  588. return func;
  589. }
  590. /**
  591. * Creates compiled iteration functions.
  592. *
  593. * @private
  594. * @param {Object} [options1, options2, ...] The compile options object(s).
  595. * arrays - A string of code to determine if the iterable is an array or array-like.
  596. * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop.
  597. * args - A string of comma separated arguments the iteration function will accept.
  598. * top - A string of code to execute before the iteration branches.
  599. * loop - A string of code to execute in the object loop.
  600. * bottom - A string of code to execute after the iteration branches.
  601. *
  602. * @returns {Function} Returns the compiled function.
  603. */
  604. function createIterator() {
  605. var data = {
  606. // support properties
  607. 'hasDontEnumBug': hasDontEnumBug,
  608. 'hasEnumPrototype': hasEnumPrototype,
  609. 'isKeysFast': isKeysFast,
  610. 'nonEnumArgs': nonEnumArgs,
  611. 'noCharByIndex': noCharByIndex,
  612. 'shadowed': shadowed,
  613. // iterator options
  614. 'arrays': 'isArray(iterable)',
  615. 'bottom': '',
  616. 'loop': '',
  617. 'top': '',
  618. 'useHas': true
  619. };
  620. // merge options into a template data object
  621. for (var object, index = 0; object = arguments[index]; index++) {
  622. for (var key in object) {
  623. data[key] = object[key];
  624. }
  625. }
  626. var args = data.args;
  627. data.firstArg = /^[^,]+/.exec(args)[0];
  628. // create the function factory
  629. var factory = Function(
  630. 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' +
  631. 'objectTypes, nativeKeys',
  632. 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
  633. );
  634. // return the compiled function
  635. return factory(
  636. createCallback, hasOwnProperty, isArguments, isArray, isString,
  637. objectTypes, nativeKeys
  638. );
  639. }
  640. /**
  641. * A function compiled to iterate `arguments` objects, arrays, objects, and
  642. * strings consistenly across environments, executing the `callback` for each
  643. * element in the `collection`. The `callback` is bound to `thisArg` and invoked
  644. * with three arguments; (value, index|key, collection). Callbacks may exit
  645. * iteration early by explicitly returning `false`.
  646. *
  647. * @private
  648. * @type Function
  649. * @param {Array|Object|String} collection The collection to iterate over.
  650. * @param {Function} [callback=identity] The function called per iteration.
  651. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  652. * @returns {Array|Object|String} Returns `collection`.
  653. */
  654. var each = createIterator(eachIteratorOptions);
  655. /**
  656. * Used by `template` to escape characters for inclusion in compiled
  657. * string literals.
  658. *
  659. * @private
  660. * @param {String} match The matched character to escape.
  661. * @returns {String} Returns the escaped character.
  662. */
  663. function escapeStringChar(match) {
  664. return '\\' + stringEscapes[match];
  665. }
  666. /**
  667. * Used by `escape` to convert characters to HTML entities.
  668. *
  669. * @private
  670. * @param {String} match The matched character to escape.
  671. * @returns {String} Returns the escaped character.
  672. */
  673. function escapeHtmlChar(match) {
  674. return htmlEscapes[match];
  675. }
  676. /**
  677. * Checks if `value` is a DOM node in IE < 9.
  678. *
  679. * @private
  680. * @param {Mixed} value The value to check.
  681. * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`.
  682. */
  683. function isNode(value) {
  684. // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
  685. // methods that are `typeof` "string" and still can coerce nodes to strings
  686. return typeof value.toString != 'function' && typeof (value + '') == 'string';
  687. }
  688. /**
  689. * A no-operation function.
  690. *
  691. * @private
  692. */
  693. function noop() {
  694. // no operation performed
  695. }
  696. /**
  697. * Slices the `collection` from the `start` index up to, but not including,
  698. * the `end` index.
  699. *
  700. * Note: This function is used, instead of `Array#slice`, to support node lists
  701. * in IE < 9 and to ensure dense arrays are returned.
  702. *
  703. * @private
  704. * @param {Array|Object|String} collection The collection to slice.
  705. * @param {Number} start The start index.
  706. * @param {Number} end The end index.
  707. * @returns {Array} Returns the new array.
  708. */
  709. function slice(array, start, end) {
  710. start || (start = 0);
  711. if (typeof end == 'undefined') {
  712. end = array ? array.length : 0;
  713. }
  714. var index = -1,
  715. length = end - start || 0,
  716. result = Array(length < 0 ? 0 : length);
  717. while (++index < length) {
  718. result[index] = array[start + index];
  719. }
  720. return result;
  721. }
  722. /**
  723. * Used by `unescape` to convert HTML entities to characters.
  724. *
  725. * @private
  726. * @param {String} match The matched character to unescape.
  727. * @returns {String} Returns the unescaped character.
  728. */
  729. function unescapeHtmlChar(match) {
  730. return htmlUnescapes[match];
  731. }
  732. /*--------------------------------------------------------------------------*/
  733. /**
  734. * Checks if `value` is an `arguments` object.
  735. *
  736. * @static
  737. * @memberOf _
  738. * @category Objects
  739. * @param {Mixed} value The value to check.
  740. * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
  741. * @example
  742. *
  743. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  744. * // => true
  745. *
  746. * _.isArguments([1, 2, 3]);
  747. * // => false
  748. */
  749. function isArguments(value) {
  750. return toString.call(value) == argsClass;
  751. }
  752. // fallback for browsers that can't detect `arguments` objects by [[Class]]
  753. if (noArgsClass) {
  754. isArguments = function(value) {
  755. return value ? hasOwnProperty.call(value, 'callee') : false;
  756. };
  757. }
  758. /**
  759. * Iterates over `object`'s own and inherited enumerable properties, executing
  760. * the `callback` for each property. The `callback` is bound to `thisArg` and
  761. * invoked with three arguments; (value, key, object). Callbacks may exit iteration
  762. * early by explicitly returning `false`.
  763. *
  764. * @static
  765. * @memberOf _
  766. * @type Function
  767. * @category Objects
  768. * @param {Object} object The object to iterate over.
  769. * @param {Function} [callback=identity] The function called per iteration.
  770. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  771. * @returns {Object} Returns `object`.
  772. * @example
  773. *
  774. * function Dog(name) {
  775. * this.name = name;
  776. * }
  777. *
  778. * Dog.prototype.bark = function() {
  779. * alert('Woof, woof!');
  780. * };
  781. *
  782. * _.forIn(new Dog('Dagny'), function(value, key) {
  783. * alert(key);
  784. * });
  785. * // => alerts 'name' and 'bark' (order is not guaranteed)
  786. */
  787. var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
  788. 'useHas': false
  789. });
  790. /**
  791. * Iterates over an object's own enumerable properties, executing the `callback`
  792. * for each property. The `callback` is bound to `thisArg` and invoked with three
  793. * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
  794. * returning `false`.
  795. *
  796. * @static
  797. * @memberOf _
  798. * @type Function
  799. * @category Objects
  800. * @param {Object} object The object to iterate over.
  801. * @param {Function} [callback=identity] The function called per iteration.
  802. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  803. * @returns {Object} Returns `object`.
  804. * @example
  805. *
  806. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  807. * alert(key);
  808. * });
  809. * // => alerts '0', '1', and 'length' (order is not guaranteed)
  810. */
  811. var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
  812. /**
  813. * Checks if `value` is an array.
  814. *
  815. * @static
  816. * @memberOf _
  817. * @category Objects
  818. * @param {Mixed} value The value to check.
  819. * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
  820. * @example
  821. *
  822. * (function() { return _.isArray(arguments); })();
  823. * // => false
  824. *
  825. * _.isArray([1, 2, 3]);
  826. * // => true
  827. */
  828. var isArray = nativeIsArray || function(value) {
  829. // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
  830. // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
  831. return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass;
  832. };
  833. /**
  834. * Creates an array composed of the own enumerable property names of `object`.
  835. *
  836. * @static
  837. * @memberOf _
  838. * @category Objects
  839. * @param {Object} object The object to inspect.
  840. * @returns {Array} Returns a new array of property names.
  841. * @example
  842. *
  843. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  844. * // => ['one', 'two', 'three'] (order is not guaranteed)
  845. */
  846. var keys = !nativeKeys ? shimKeys : function(object) {
  847. if (!isObject(object)) {
  848. return [];
  849. }
  850. if ((hasEnumPrototype && typeof object == 'function') ||
  851. (nonEnumArgs && object.length && isArguments(object))) {
  852. return shimKeys(object);
  853. }
  854. return nativeKeys(object);
  855. };
  856. /**
  857. * A fallback implementation of `isPlainObject` that checks if a given `value`
  858. * is an object created by the `Object` constructor, assuming objects created
  859. * by the `Object` constructor have no inherited enumerable properties and that
  860. * there are no `Object.prototype` extensions.
  861. *
  862. * @private
  863. * @param {Mixed} value The value to check.
  864. * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`.
  865. */
  866. function shimIsPlainObject(value) {
  867. // avoid non-objects and false positives for `arguments` objects
  868. var result = false;
  869. if (!(value && typeof value == 'object') || isArguments(value)) {
  870. return result;
  871. }
  872. // check that the constructor is `Object` (i.e. `Object instanceof Object`)
  873. var ctor = value.constructor;
  874. if ((!isFunction(ctor) && (!noNodeClass || !isNode(value))) || ctor instanceof ctor) {
  875. // IE < 9 iterates inherited properties before own properties. If the first
  876. // iterated property is an object's own property then there are no inherited
  877. // enumerable properties.
  878. if (iteratesOwnLast) {
  879. forIn(value, function(value, key, object) {
  880. result = !hasOwnProperty.call(object, key);
  881. return false;
  882. });
  883. return result === false;
  884. }
  885. // In most environments an object's own properties are iterated before
  886. // its inherited properties. If the last iterated property is an object's
  887. // own property then there are no inherited enumerable properties.
  888. forIn(value, function(value, key) {
  889. result = key;
  890. });
  891. return result === false || hasOwnProperty.call(value, result);
  892. }
  893. return result;
  894. }
  895. /**
  896. * A fallback implementation of `Object.keys` that produces an array of the
  897. * given object's own enumerable property names.
  898. *
  899. * @private
  900. * @param {Object} object The object to inspect.
  901. * @returns {Array} Returns a new array of property names.
  902. */
  903. function shimKeys(object) {
  904. var result = [];
  905. forOwn(object, function(value, key) {
  906. result.push(key);
  907. });
  908. return result;
  909. }
  910. /**
  911. * Used to convert characters to HTML entities:
  912. *
  913. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  914. * don't require escaping in HTML and have no special meaning unless they're part
  915. * of a tag or an unquoted attribute value.
  916. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  917. */
  918. var htmlEscapes = {
  919. '&': '&amp;',
  920. '<': '&lt;',
  921. '>': '&gt;',
  922. '"': '&quot;',
  923. "'": '&#39;'
  924. };
  925. /** Used to convert HTML entities to characters */
  926. var htmlUnescapes = invert(htmlEscapes);
  927. /*--------------------------------------------------------------------------*/
  928. /**
  929. * Assigns own enumerable properties of source object(s) to the destination
  930. * object. Subsequent sources will overwrite propery assignments of previous
  931. * sources. If a `callback` function is passed, it will be executed to produce
  932. * the assigned values. The `callback` is bound to `thisArg` and invoked with
  933. * two arguments; (objectValue, sourceValue).
  934. *
  935. * @static
  936. * @memberOf _
  937. * @type Function
  938. * @alias extend
  939. * @category Objects
  940. * @param {Object} object The destination object.
  941. * @param {Object} [source1, source2, ...] The source objects.
  942. * @param {Function} [callback] The function to customize assigning values.
  943. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  944. * @returns {Object} Returns the destination object.
  945. * @example
  946. *
  947. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  948. * // => { 'name': 'moe', 'age': 40 }
  949. *
  950. * var defaults = _.partialRight(_.assign, function(a, b) {
  951. * return typeof a == 'undefined' ? b : a;
  952. * });
  953. *
  954. * var food = { 'name': 'apple' };
  955. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  956. * // => { 'name': 'apple', 'type': 'fruit' }
  957. */
  958. var assign = createIterator(defaultsIteratorOptions, {
  959. 'top':
  960. defaultsIteratorOptions.top.replace(';',
  961. ';\n' +
  962. "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
  963. ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
  964. "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
  965. ' callback = args[--argsLength];\n' +
  966. '}'
  967. ),
  968. 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
  969. });
  970. /**
  971. * Creates a clone of `value`. If `deep` is `true`, nested objects will also
  972. * be cloned, otherwise they will be assigned by reference. If a `callback`
  973. * function is passed, it will be executed to produce the cloned values. If
  974. * `callback` returns `undefined`, cloning will be handled by the method instead.
  975. * The `callback` is bound to `thisArg` and invoked with one argument; (value).
  976. *
  977. * @static
  978. * @memberOf _
  979. * @category Objects
  980. * @param {Mixed} value The value to clone.
  981. * @param {Boolean} [deep=false] A flag to indicate a deep clone.
  982. * @param {Function} [callback] The function to customize cloning values.
  983. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  984. * @param- {Array} [stackA=[]] Internally used to track traversed source objects.
  985. * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts.
  986. * @returns {Mixed} Returns the cloned `value`.
  987. * @example
  988. *
  989. * var stooges = [
  990. * { 'name': 'moe', 'age': 40 },
  991. * { 'name': 'larry', 'age': 50 }
  992. * ];
  993. *
  994. * var shallow = _.clone(stooges);
  995. * shallow[0] === stooges[0];
  996. * // => true
  997. *
  998. * var deep = _.clone(stooges, true);
  999. * deep[0] === stooges[0];
  1000. * // => false
  1001. *
  1002. * _.mixin({
  1003. * 'clone': _.partialRight(_.clone, function(value) {
  1004. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  1005. * })
  1006. * });
  1007. *
  1008. * var clone = _.clone(document.body);
  1009. * clone.childNodes.length;
  1010. * // => 0
  1011. */
  1012. function clone(value, deep, callback, thisArg, stackA, stackB) {
  1013. var result = value;
  1014. // allows working with "Collections" methods without using their `callback`
  1015. // argument, `index|key`, for this method's `callback`
  1016. if (typeof deep == 'function') {
  1017. thisArg = callback;
  1018. callback = deep;
  1019. deep = false;
  1020. }
  1021. if (typeof callback == 'function') {
  1022. callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1);
  1023. result = callback(result);
  1024. var done = typeof result != 'undefined';
  1025. if (!done) {
  1026. result = value;
  1027. }
  1028. }
  1029. // inspect [[Class]]
  1030. var isObj = isObject(result);
  1031. if (isObj) {
  1032. var className = toString.call(result);
  1033. if (!cloneableClasses[className] || (noNodeClass && isNode(result))) {
  1034. return result;
  1035. }
  1036. var isArr = isArray(result);
  1037. }
  1038. // shallow clone
  1039. if (!isObj || !deep) {
  1040. return isObj && !done
  1041. ? (isArr ? slice(result) : assign({}, result))
  1042. : result;
  1043. }
  1044. var ctor = ctorByClass[className];
  1045. switch (className) {
  1046. case boolClass:
  1047. case dateClass:
  1048. return done ? result : new ctor(+result);
  1049. case numberClass:
  1050. case stringClass:
  1051. return done ? result : new ctor(result);
  1052. case regexpClass:
  1053. return done ? result : ctor(result.source, reFlags.exec(result));
  1054. }
  1055. // check for circular references and return corresponding clone
  1056. stackA || (stackA = []);
  1057. stackB || (stackB = []);
  1058. var length = stackA.length;
  1059. while (length--) {
  1060. if (stackA[length] == value) {
  1061. return stackB[length];
  1062. }
  1063. }
  1064. // init cloned object
  1065. if (!done) {
  1066. result = isArr ? ctor(result.length) : {};
  1067. // add array properties assigned by `RegExp#exec`
  1068. if (isArr) {
  1069. if (hasOwnProperty.call(value, 'index')) {
  1070. result.index = value.index;
  1071. }
  1072. if (hasOwnProperty.call(value, 'input')) {
  1073. result.input = value.input;
  1074. }
  1075. }
  1076. }
  1077. // add the source value to the stack of traversed objects
  1078. // and associate it with its clone
  1079. stackA.push(value);
  1080. stackB.push(result);
  1081. // recursively populate clone (susceptible to call stack limits)
  1082. (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) {
  1083. result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
  1084. });
  1085. return result;
  1086. }
  1087. /**
  1088. * Creates a deep clone of `value`. If a `callback` function is passed, it will
  1089. * be executed to produce the cloned values. If `callback` returns the value it
  1090. * was passed, cloning will be handled by the method instead. The `callback` is
  1091. * bound to `thisArg` and invoked with one argument; (value).
  1092. *
  1093. * Note: This function is loosely based on the structured clone algorithm. Functions
  1094. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  1095. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  1096. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  1097. *
  1098. * @static
  1099. * @memberOf _
  1100. * @category Objects
  1101. * @param {Mixed} value The value to deep clone.
  1102. * @param {Function} [callback] The function to customize cloning values.
  1103. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1104. * @returns {Mixed} Returns the deep cloned `value`.
  1105. * @example
  1106. *
  1107. * var stooges = [
  1108. * { 'name': 'moe', 'age': 40 },
  1109. * { 'name': 'larry', 'age': 50 }
  1110. * ];
  1111. *
  1112. * var deep = _.cloneDeep(stooges);
  1113. * deep[0] === stooges[0];
  1114. * // => false
  1115. *
  1116. * var view = {
  1117. * 'label': 'docs',
  1118. * 'node': element
  1119. * };
  1120. *
  1121. * var clone = _.cloneDeep(view, function(value) {
  1122. * return _.isElement(value) ? value.cloneNode(true) : value;
  1123. * });
  1124. *
  1125. * clone.node == view.node;
  1126. * // => false
  1127. */
  1128. function cloneDeep(value, callback, thisArg) {
  1129. return clone(value, true, callback, thisArg);
  1130. }
  1131. /**
  1132. * Assigns own enumerable properties of source object(s) to the destination
  1133. * object for all destination properties that resolve to `undefined`. Once a
  1134. * property is set, additional defaults of the same property will be ignored.
  1135. *
  1136. * @static
  1137. * @memberOf _
  1138. * @type Function
  1139. * @category Objects
  1140. * @param {Object} object The destination object.
  1141. * @param {Object} [source1, source2, ...] The source objects.
  1142. * @param- {Object} [guard] Internally used to allow working with `_.reduce`
  1143. * without using its callback's `key` and `object` arguments as sources.
  1144. * @returns {Object} Returns the destination object.
  1145. * @example
  1146. *
  1147. * var food = { 'name': 'apple' };
  1148. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  1149. * // => { 'name': 'apple', 'type': 'fruit' }
  1150. */
  1151. var defaults = createIterator(defaultsIteratorOptions);
  1152. /**
  1153. * Creates a sorted array of all enumerable properties, own and inherited,
  1154. * of `object` that have function values.
  1155. *
  1156. * @static
  1157. * @memberOf _
  1158. * @alias methods
  1159. * @category Objects
  1160. * @param {Object} object The object to inspect.
  1161. * @returns {Array} Returns a new array of property names that have function values.
  1162. * @example
  1163. *
  1164. * _.functions(_);
  1165. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  1166. */
  1167. function functions(object) {
  1168. var result = [];
  1169. forIn(object, function(value, key) {
  1170. if (isFunction(value)) {
  1171. result.push(key);
  1172. }
  1173. });
  1174. return result.sort();
  1175. }
  1176. /**
  1177. * Checks if the specified object `property` exists and is a direct property,
  1178. * instead of an inherited property.
  1179. *
  1180. * @static
  1181. * @memberOf _
  1182. * @category Objects
  1183. * @param {Object} object The object to check.
  1184. * @param {String} property The property to check for.
  1185. * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
  1186. * @example
  1187. *
  1188. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  1189. * // => true
  1190. */
  1191. function has(object, property) {
  1192. return object ? hasOwnProperty.call(object, property) : false;
  1193. }
  1194. /**
  1195. * Creates an object composed of the inverted keys and values of the given `object`.
  1196. *
  1197. * @static
  1198. * @memberOf _
  1199. * @category Objects
  1200. * @param {Object} object The object to invert.
  1201. * @returns {Object} Returns the created inverted object.
  1202. * @example
  1203. *
  1204. * _.invert({ 'first': 'moe', 'second': 'larry' });
  1205. * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed)
  1206. */
  1207. function invert(object) {
  1208. var index = -1,
  1209. props = keys(object),
  1210. length = props.length,
  1211. result = {};
  1212. while (++index < length) {
  1213. var key = props[index];
  1214. result[object[key]] = key;
  1215. }
  1216. return result;
  1217. }
  1218. /**
  1219. * Checks if `value` is a boolean value.
  1220. *
  1221. * @static
  1222. * @memberOf _
  1223. * @category Objects
  1224. * @param {Mixed} value The value to check.
  1225. * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
  1226. * @example
  1227. *
  1228. * _.isBoolean(null);
  1229. * // => false
  1230. */
  1231. function isBoolean(value) {
  1232. return value === true || value === false || toString.call(value) == boolClass;
  1233. }
  1234. /**
  1235. * Checks if `value` is a date.
  1236. *
  1237. * @static
  1238. * @memberOf _
  1239. * @category Objects
  1240. * @param {Mixed} value The value to check.
  1241. * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
  1242. * @example
  1243. *
  1244. * _.isDate(new Date);
  1245. * // => true
  1246. */
  1247. function isDate(value) {
  1248. return value instanceof Date || toString.call(value) == dateClass;
  1249. }
  1250. /**
  1251. * Checks if `value` is a DOM element.
  1252. *
  1253. * @static
  1254. * @memberOf _
  1255. * @category Objects
  1256. * @param {Mixed} value The value to check.
  1257. * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
  1258. * @example
  1259. *
  1260. * _.isElement(document.body);
  1261. * // => true
  1262. */
  1263. function isElement(value) {
  1264. return value ? value.nodeType === 1 : false;
  1265. }
  1266. /**
  1267. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  1268. * length of `0` and objects with no own enumerable properties are considered
  1269. * "empty".
  1270. *
  1271. * @static
  1272. * @memberOf _
  1273. * @category Objects
  1274. * @param {Array|Object|String} value The value to inspect.
  1275. * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
  1276. * @example
  1277. *
  1278. * _.isEmpty([1, 2, 3]);
  1279. * // => false
  1280. *
  1281. * _.isEmpty({});
  1282. * // => true
  1283. *
  1284. * _.isEmpty('');
  1285. * // => true
  1286. */
  1287. function isEmpty(value) {
  1288. var result = true;
  1289. if (!value) {
  1290. return result;
  1291. }
  1292. var className = toString.call(value),
  1293. length = value.length;
  1294. if ((className == arrayClass || className == stringClass ||
  1295. className == argsClass || (noArgsClass && isArguments(value))) ||
  1296. (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
  1297. return !length;
  1298. }
  1299. forOwn(value, function() {
  1300. return (result = false);
  1301. });
  1302. return result;
  1303. }
  1304. /**
  1305. * Performs a deep comparison between two values to determine if they are
  1306. * equivalent to each other. If `callback` is passed, it will be executed to
  1307. * compare values. If `callback` returns `undefined`, comparisons will be handled
  1308. * by the method instead. The `callback` is bound to `thisArg` and invoked with
  1309. * two arguments; (a, b).
  1310. *
  1311. * @static
  1312. * @memberOf _
  1313. * @category Objects
  1314. * @param {Mixed} a The value to compare.
  1315. * @param {Mixed} b The other value to compare.
  1316. * @param {Function} [callback] The function to customize comparing values.
  1317. * @param {Mixed} [thisArg] The `this` binding of `callback`.
  1318. * @param- {Object} [stackA=[]] Internally used track traversed `a` objects.
  1319. * @param- {Object} [stackB=[]] Internally used track traversed `b` objects.
  1320. * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`.
  1321. * @example
  1322. *
  1323. * var moe = { 'name': 'moe', 'age': 40 };
  1324. * var copy = { 'name': 'moe', 'age': 40 };
  1325. *
  1326. * moe == copy;
  1327. * // => false
  1328. *
  1329. * _.isEqual(moe, copy);
  1330. * // => true
  1331. *
  1332. * var words = ['hello', 'goodbye'];
  1333. * var otherWords = ['hi', 'goodbye'];
  1334. *
  1335. * _.isEqual(words, otherWords, function(a, b) {
  1336. * var reGreet = /^(?:hello|hi)$/i,
  1337. * aGreet = _.isString(a) && reGreet.test(a),
  1338. * bGreet = _.isString(b) && reGreet.test(b);
  1339. *
  1340. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  1341. * });
  1342. * // => true
  1343. */
  1344. function isEqual(a, b, callback, thisArg, stackA, stackB) {
  1345. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  1346. var whereIndicator = callback === indicatorObject;
  1347. if (callback && !whereIndicator) {
  1348. callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2);
  1349. var result = callback(a, b);
  1350. if (typeof result != 'undefined') {
  1351. return !!result;
  1352. }
  1353. }
  1354. // exit early for identical values
  1355. if (a === b) {
  1356. // treat `+0` vs. `-0` as not equal
  1357. return a !== 0 || (1 / a == 1 / b);
  1358. }
  1359. var type = typeof a,
  1360. otherType = typeof b;
  1361. // exit early for unlike primitive values
  1362. if (a === a &&
  1363. (!a || (type != 'function' && type != 'object')) &&
  1364. (!b || (otherType != 'function' && otherType != 'object'))) {
  1365. return false;
  1366. }
  1367. // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior
  1368. // http://es5.github.com/#x15.3.4.4
  1369. if (a == null || b == null) {
  1370. return a === b;
  1371. }
  1372. // compare [[Class]] names
  1373. var className = toString.call(a),
  1374. otherClass = toString.call(b);
  1375. if (className == argsClass) {
  1376. className = objectClass;
  1377. }
  1378. if (otherClass == argsClass) {
  1379. otherClass = objectClass;
  1380. }
  1381. if (className != otherClass) {
  1382. return false;
  1383. }
  1384. switch (className) {
  1385. case boolClass:
  1386. case dateClass:
  1387. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  1388. // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal
  1389. return +a == +b;
  1390. case numb