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