* @ngdoc function * @name angular.copy * @module ng * @kind function * * @description * Creates a deep copy of `source`, which should be an object or an array. * * * If no destination is supplied, a copy of the object or array is created. * * If a destination is provided, all of its element
(source, destination, maxDepth)
| 968 | </example> |
| 969 | */ |
| 970 | function copy(source, destination, maxDepth) { |
| 971 | var stackSource = []; |
| 972 | var stackDest = []; |
| 973 | maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN; |
| 974 | |
| 975 | if (destination) { |
| 976 | if (isTypedArray(destination) || isArrayBuffer(destination)) { |
| 977 | throw ngMinErr('cpta', 'Can\'t copy! TypedArray destination cannot be mutated.'); |
| 978 | } |
| 979 | if (source === destination) { |
| 980 | throw ngMinErr('cpi', 'Can\'t copy! Source and destination are identical.'); |
| 981 | } |
| 982 | |
| 983 | // Empty the destination object |
| 984 | if (isArray(destination)) { |
| 985 | destination.length = 0; |
| 986 | } else { |
| 987 | forEach(destination, function(value, key) { |
| 988 | if (key !== '$$hashKey') { |
| 989 | delete destination[key]; |
| 990 | } |
| 991 | }); |
| 992 | } |
| 993 | |
| 994 | stackSource.push(source); |
| 995 | stackDest.push(destination); |
| 996 | return copyRecurse(source, destination, maxDepth); |
| 997 | } |
| 998 | |
| 999 | return copyElement(source, maxDepth); |
| 1000 | |
| 1001 | function copyRecurse(source, destination, maxDepth) { |
| 1002 | maxDepth--; |
| 1003 | if (maxDepth < 0) { |
| 1004 | return '...'; |
| 1005 | } |
| 1006 | var h = destination.$$hashKey; |
| 1007 | var key; |
| 1008 | if (isArray(source)) { |
| 1009 | for (var i = 0, ii = source.length; i < ii; i++) { |
| 1010 | destination.push(copyElement(source[i], maxDepth)); |
| 1011 | } |
| 1012 | } else if (isBlankObject(source)) { |
| 1013 | // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty |
| 1014 | for (key in source) { |
| 1015 | destination[key] = copyElement(source[key], maxDepth); |
| 1016 | } |
| 1017 | } else if (source && typeof source.hasOwnProperty === 'function') { |
| 1018 | // Slow path, which must rely on hasOwnProperty |
| 1019 | for (key in source) { |
| 1020 | if (source.hasOwnProperty(key)) { |
| 1021 | destination[key] = copyElement(source[key], maxDepth); |
| 1022 | } |
| 1023 | } |
| 1024 | } else { |
| 1025 | // Slowest path --- hasOwnProperty can't be called as a method |
| 1026 | for (key in source) { |
| 1027 | if (hasOwnProperty.call(source, key)) { |
no test coverage detected