Initial commit
[yaffs-website] / node_modules / grunt-contrib-watch / node_modules / lodash / internal / baseClone.js
1 var arrayCopy = require('./arrayCopy'),
2     arrayEach = require('./arrayEach'),
3     baseAssign = require('./baseAssign'),
4     baseForOwn = require('./baseForOwn'),
5     initCloneArray = require('./initCloneArray'),
6     initCloneByTag = require('./initCloneByTag'),
7     initCloneObject = require('./initCloneObject'),
8     isArray = require('../lang/isArray'),
9     isObject = require('../lang/isObject');
10
11 /** `Object#toString` result references. */
12 var argsTag = '[object Arguments]',
13     arrayTag = '[object Array]',
14     boolTag = '[object Boolean]',
15     dateTag = '[object Date]',
16     errorTag = '[object Error]',
17     funcTag = '[object Function]',
18     mapTag = '[object Map]',
19     numberTag = '[object Number]',
20     objectTag = '[object Object]',
21     regexpTag = '[object RegExp]',
22     setTag = '[object Set]',
23     stringTag = '[object String]',
24     weakMapTag = '[object WeakMap]';
25
26 var arrayBufferTag = '[object ArrayBuffer]',
27     float32Tag = '[object Float32Array]',
28     float64Tag = '[object Float64Array]',
29     int8Tag = '[object Int8Array]',
30     int16Tag = '[object Int16Array]',
31     int32Tag = '[object Int32Array]',
32     uint8Tag = '[object Uint8Array]',
33     uint8ClampedTag = '[object Uint8ClampedArray]',
34     uint16Tag = '[object Uint16Array]',
35     uint32Tag = '[object Uint32Array]';
36
37 /** Used to identify `toStringTag` values supported by `_.clone`. */
38 var cloneableTags = {};
39 cloneableTags[argsTag] = cloneableTags[arrayTag] =
40 cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
41 cloneableTags[dateTag] = cloneableTags[float32Tag] =
42 cloneableTags[float64Tag] = cloneableTags[int8Tag] =
43 cloneableTags[int16Tag] = cloneableTags[int32Tag] =
44 cloneableTags[numberTag] = cloneableTags[objectTag] =
45 cloneableTags[regexpTag] = cloneableTags[stringTag] =
46 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
47 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
48 cloneableTags[errorTag] = cloneableTags[funcTag] =
49 cloneableTags[mapTag] = cloneableTags[setTag] =
50 cloneableTags[weakMapTag] = false;
51
52 /** Used for native method references. */
53 var objectProto = Object.prototype;
54
55 /**
56  * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
57  * of values.
58  */
59 var objToString = objectProto.toString;
60
61 /**
62  * The base implementation of `_.clone` without support for argument juggling
63  * and `this` binding `customizer` functions.
64  *
65  * @private
66  * @param {*} value The value to clone.
67  * @param {boolean} [isDeep] Specify a deep clone.
68  * @param {Function} [customizer] The function to customize cloning values.
69  * @param {string} [key] The key of `value`.
70  * @param {Object} [object] The object `value` belongs to.
71  * @param {Array} [stackA=[]] Tracks traversed source objects.
72  * @param {Array} [stackB=[]] Associates clones with source counterparts.
73  * @returns {*} Returns the cloned value.
74  */
75 function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
76   var result;
77   if (customizer) {
78     result = object ? customizer(value, key, object) : customizer(value);
79   }
80   if (result !== undefined) {
81     return result;
82   }
83   if (!isObject(value)) {
84     return value;
85   }
86   var isArr = isArray(value);
87   if (isArr) {
88     result = initCloneArray(value);
89     if (!isDeep) {
90       return arrayCopy(value, result);
91     }
92   } else {
93     var tag = objToString.call(value),
94         isFunc = tag == funcTag;
95
96     if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
97       result = initCloneObject(isFunc ? {} : value);
98       if (!isDeep) {
99         return baseAssign(result, value);
100       }
101     } else {
102       return cloneableTags[tag]
103         ? initCloneByTag(value, tag, isDeep)
104         : (object ? value : {});
105     }
106   }
107   // Check for circular references and return its corresponding clone.
108   stackA || (stackA = []);
109   stackB || (stackB = []);
110
111   var length = stackA.length;
112   while (length--) {
113     if (stackA[length] == value) {
114       return stackB[length];
115     }
116   }
117   // Add the source value to the stack of traversed objects and associate it with its clone.
118   stackA.push(value);
119   stackB.push(result);
120
121   // Recursively populate clone (susceptible to call stack limits).
122   (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
123     result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
124   });
125   return result;
126 }
127
128 module.exports = baseClone;