* @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, stackSource, stackDest)
| 862 | </example> |
| 863 | */ |
| 864 | function copy(source, destination, stackSource, stackDest) { |
| 865 | if (isWindow(source) || isScope(source)) { |
| 866 | throw ngMinErr('cpws', |
| 867 | "Can't copy! Making copies of Window or Scope instances is not supported."); |
| 868 | } |
| 869 | if (isTypedArray(destination)) { |
| 870 | throw ngMinErr('cpta', |
| 871 | "Can't copy! TypedArray destination cannot be mutated."); |
| 872 | } |
| 873 | |
| 874 | if (!destination) { |
| 875 | destination = source; |
| 876 | if (isObject(source)) { |
| 877 | var index; |
| 878 | if (stackSource && (index = stackSource.indexOf(source)) !== -1) { |
| 879 | return stackDest[index]; |
| 880 | } |
| 881 | |
| 882 | // TypedArray, Date and RegExp have specific copy functionality and must be |
| 883 | // pushed onto the stack before returning. |
| 884 | // Array and other objects create the base object and recurse to copy child |
| 885 | // objects. The array/object will be pushed onto the stack when recursed. |
| 886 | if (isArray(source)) { |
| 887 | return copy(source, [], stackSource, stackDest); |
| 888 | } else if (isTypedArray(source)) { |
| 889 | destination = new source.constructor(source); |
| 890 | } else if (isDate(source)) { |
| 891 | destination = new Date(source.getTime()); |
| 892 | } else if (isRegExp(source)) { |
| 893 | destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); |
| 894 | destination.lastIndex = source.lastIndex; |
| 895 | } else { |
| 896 | var emptyObject = Object.create(getPrototypeOf(source)); |
| 897 | return copy(source, emptyObject, stackSource, stackDest); |
| 898 | } |
| 899 | |
| 900 | if (stackDest) { |
| 901 | stackSource.push(source); |
| 902 | stackDest.push(destination); |
| 903 | } |
| 904 | } |
| 905 | } else { |
| 906 | if (source === destination) throw ngMinErr('cpi', |
| 907 | "Can't copy! Source and destination are identical."); |
| 908 | |
| 909 | stackSource = stackSource || []; |
| 910 | stackDest = stackDest || []; |
| 911 | |
| 912 | if (isObject(source)) { |
| 913 | stackSource.push(source); |
| 914 | stackDest.push(destination); |
| 915 | } |
| 916 | |
| 917 | var result, key; |
| 918 | if (isArray(source)) { |
| 919 | destination.length = 0; |
| 920 | for (var i = 0; i < source.length; i++) { |
| 921 | destination.push(copy(source[i], null, stackSource, stackDest)); |
no test coverage detected