* @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)
| 852 | </example> |
| 853 | */ |
| 854 | function copy(source, destination, stackSource, stackDest) { |
| 855 | if (isWindow(source) || isScope(source)) { |
| 856 | throw ngMinErr('cpws', |
| 857 | "Can't copy! Making copies of Window or Scope instances is not supported."); |
| 858 | } |
| 859 | |
| 860 | if (!destination) { |
| 861 | destination = source; |
| 862 | if (source) { |
| 863 | if (isArray(source)) { |
| 864 | destination = copy(source, [], stackSource, stackDest); |
| 865 | } else if (isDate(source)) { |
| 866 | destination = new Date(source.getTime()); |
| 867 | } else if (isRegExp(source)) { |
| 868 | destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); |
| 869 | destination.lastIndex = source.lastIndex; |
| 870 | } else if (isObject(source)) { |
| 871 | destination = copy(source, {}, stackSource, stackDest); |
| 872 | } |
| 873 | } |
| 874 | } else { |
| 875 | if (source === destination) throw ngMinErr('cpi', |
| 876 | "Can't copy! Source and destination are identical."); |
| 877 | |
| 878 | stackSource = stackSource || []; |
| 879 | stackDest = stackDest || []; |
| 880 | |
| 881 | if (isObject(source)) { |
| 882 | var index = indexOf(stackSource, source); |
| 883 | if (index !== -1) return stackDest[index]; |
| 884 | |
| 885 | stackSource.push(source); |
| 886 | stackDest.push(destination); |
| 887 | } |
| 888 | |
| 889 | var result; |
| 890 | if (isArray(source)) { |
| 891 | destination.length = 0; |
| 892 | for ( var i = 0; i < source.length; i++) { |
| 893 | result = copy(source[i], null, stackSource, stackDest); |
| 894 | if (isObject(source[i])) { |
| 895 | stackSource.push(source[i]); |
| 896 | stackDest.push(result); |
| 897 | } |
| 898 | destination.push(result); |
| 899 | } |
| 900 | } else { |
| 901 | var h = destination.$$hashKey; |
| 902 | forEach(destination, function(value, key) { |
| 903 | delete destination[key]; |
| 904 | }); |
| 905 | for ( var key in source) { |
| 906 | result = copy(source[key], null, stackSource, stackDest); |
| 907 | if (isObject(source[key])) { |
| 908 | stackSource.push(source[key]); |
| 909 | stackDest.push(result); |
| 910 | } |
| 911 | destination[key] = result; |
no test coverage detected