/plugins/cordova-plugin-disable-bitcode/node_modules/lodash-node/modern/internals/baseClone.js

https://gitlab.com/blocknotary/IonicInterviews · JavaScript · 152 lines · 104 code · 14 blank · 34 comment · 19 complexity · 6a13fe9941a1803823558b39973d24d9 MD5 · raw file

  1. /**
  2. * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
  3. * Build: `lodash modularize modern exports="node" -o ./modern/`
  4. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  5. * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
  6. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  7. * Available under MIT license <http://lodash.com/license>
  8. */
  9. var assign = require('../objects/assign'),
  10. forEach = require('../collections/forEach'),
  11. forOwn = require('../objects/forOwn'),
  12. getArray = require('./getArray'),
  13. isArray = require('../objects/isArray'),
  14. isObject = require('../objects/isObject'),
  15. releaseArray = require('./releaseArray'),
  16. slice = require('./slice');
  17. /** Used to match regexp flags from their coerced string values */
  18. var reFlags = /\w*$/;
  19. /** `Object#toString` result shortcuts */
  20. var argsClass = '[object Arguments]',
  21. arrayClass = '[object Array]',
  22. boolClass = '[object Boolean]',
  23. dateClass = '[object Date]',
  24. funcClass = '[object Function]',
  25. numberClass = '[object Number]',
  26. objectClass = '[object Object]',
  27. regexpClass = '[object RegExp]',
  28. stringClass = '[object String]';
  29. /** Used to identify object classifications that `_.clone` supports */
  30. var cloneableClasses = {};
  31. cloneableClasses[funcClass] = false;
  32. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  33. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  34. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  35. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  36. /** Used for native method references */
  37. var objectProto = Object.prototype;
  38. /** Used to resolve the internal [[Class]] of values */
  39. var toString = objectProto.toString;
  40. /** Native method shortcuts */
  41. var hasOwnProperty = objectProto.hasOwnProperty;
  42. /** Used to lookup a built-in constructor by [[Class]] */
  43. var ctorByClass = {};
  44. ctorByClass[arrayClass] = Array;
  45. ctorByClass[boolClass] = Boolean;
  46. ctorByClass[dateClass] = Date;
  47. ctorByClass[funcClass] = Function;
  48. ctorByClass[objectClass] = Object;
  49. ctorByClass[numberClass] = Number;
  50. ctorByClass[regexpClass] = RegExp;
  51. ctorByClass[stringClass] = String;
  52. /**
  53. * The base implementation of `_.clone` without argument juggling or support
  54. * for `thisArg` binding.
  55. *
  56. * @private
  57. * @param {*} value The value to clone.
  58. * @param {boolean} [isDeep=false] Specify a deep clone.
  59. * @param {Function} [callback] The function to customize cloning values.
  60. * @param {Array} [stackA=[]] Tracks traversed source objects.
  61. * @param {Array} [stackB=[]] Associates clones with source counterparts.
  62. * @returns {*} Returns the cloned value.
  63. */
  64. function baseClone(value, isDeep, callback, stackA, stackB) {
  65. if (callback) {
  66. var result = callback(value);
  67. if (typeof result != 'undefined') {
  68. return result;
  69. }
  70. }
  71. // inspect [[Class]]
  72. var isObj = isObject(value);
  73. if (isObj) {
  74. var className = toString.call(value);
  75. if (!cloneableClasses[className]) {
  76. return value;
  77. }
  78. var ctor = ctorByClass[className];
  79. switch (className) {
  80. case boolClass:
  81. case dateClass:
  82. return new ctor(+value);
  83. case numberClass:
  84. case stringClass:
  85. return new ctor(value);
  86. case regexpClass:
  87. result = ctor(value.source, reFlags.exec(value));
  88. result.lastIndex = value.lastIndex;
  89. return result;
  90. }
  91. } else {
  92. return value;
  93. }
  94. var isArr = isArray(value);
  95. if (isDeep) {
  96. // check for circular references and return corresponding clone
  97. var initedStack = !stackA;
  98. stackA || (stackA = getArray());
  99. stackB || (stackB = getArray());
  100. var length = stackA.length;
  101. while (length--) {
  102. if (stackA[length] == value) {
  103. return stackB[length];
  104. }
  105. }
  106. result = isArr ? ctor(value.length) : {};
  107. }
  108. else {
  109. result = isArr ? slice(value) : assign({}, value);
  110. }
  111. // add array properties assigned by `RegExp#exec`
  112. if (isArr) {
  113. if (hasOwnProperty.call(value, 'index')) {
  114. result.index = value.index;
  115. }
  116. if (hasOwnProperty.call(value, 'input')) {
  117. result.input = value.input;
  118. }
  119. }
  120. // exit for shallow clone
  121. if (!isDeep) {
  122. return result;
  123. }
  124. // add the source value to the stack of traversed objects
  125. // and associate it with its clone
  126. stackA.push(value);
  127. stackB.push(result);
  128. // recursively populate clone (susceptible to call stack limits)
  129. (isArr ? forEach : forOwn)(value, function(objValue, key) {
  130. result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
  131. });
  132. if (initedStack) {
  133. releaseArray(stackA);
  134. releaseArray(stackB);
  135. }
  136. return result;
  137. }
  138. module.exports = baseClone;