47

I'm working on a project that has both Angular and Underscore as a dependency.

When I need to create a copy of an object, depending on my mood at the time, I might use angular.copy() or _.clone()

It occurs to me that one of these methods is probably more fast/reliable/robust than the other.

Are there any known issue with either of these functions that make it better or worse to use than the other, assuming both libraries are already included?

Code Whisperer
  • 22,959
  • 20
  • 67
  • 85
  • 1
    Do you have any results from comparisons that you have already ran, possibly with jsperf? or have you done no research yet. – Kevin B Oct 16 '14 at 18:53
  • 4
    the two methods clearly perform two different tasks, according to the documentation, (deep copy vs shallow copy) therefore the best to use would be dependent on what exactly you wanted to do in each case. – Kevin B Oct 16 '14 at 18:55
  • 1
    So, lodash has a cloneDeep method and also if you pass in a boolean to lodash's clone method it creates a deep clone according to the documentation. Any suggestions over performance of those methods versus angular.copy? – Dewey Vozel Jul 23 '15 at 19:44

2 Answers2

42

Regarding your question: angular.copy and _.clone are different. It's not a question of which is better, it is about what you need as @Kevin B stated in the comments.

angular.extend() on the other hand, is a shallow copy akin to _.clone

Angular.copy vs Angular.extend

Performance wise, i'm not sure which is better, but for opinions sake, i'm opposed to including libraries into the global scope (underscore) with any angular app, as usually these things are written as angular modules. angular.copy/angular.extend would win in this case.

Shallow/Deep Copy:

Its very simple that if the object has only primitive fields, then obviously you will go for shallow copy but if the object has references to other objects, then based on the requiement, shallow copy or deep copy should be chosen. What I mean here is, if the references are not modified anytime, then there is no point in going for deep copy. You can just opt shallow copy. But if the references are modified often, then you need to go for deep copy. Again there is no hard and fast rule, it all depends on the requirement.

Source

dannypaz
  • 1,294
  • 1
  • 12
  • 16
  • 2
    "But if the references are modified often, then you need to go for deep copy." I would instead say that if the references are modified then it probably does matter whether you do deep or shallow, but if they aren't then it probably doesn't matter. In fact I'd say that in the cases where references are modified, you'd more often want to use a shallow copy. But as livepo said, you need to decide on a case-by-case basis. As for performance, as a general rule shallow clone should be faster than deep clone, especially for deep data structures. For shallow structures, it might depend on the library. – David Knipe Oct 16 '14 at 20:08
  • 1
    I usually include underscore as a service in apps that need to do extensive data transformations. This prevents you from having to use the global `_`. This approach also works nicely for other useful, self-contained libraries, e.g. momentjs. – Jannik Jochem Apr 24 '15 at 07:31
  • 2
    I bet your answer would be different now in 2016. You can very easily use dependency injection (not angular's) using common or require and have access to underscore or lodash. Lodash has been found to be faster than native browser methods in some cases, such as _.forEach in Chrome. Can be very important in a large scale data application. – bwinchester Oct 21 '16 at 13:53
  • 4
    The link provided (Angular.copy vs Angular.extend) does not work anymore – Icarus Mar 23 '17 at 20:27
4

We had some bug reports confirming that using angular.copy does create empty objects on some Windows mobile phones. So if you need to support any version of IE on mobile, don't use angular.copy! Allegedly this bug has been fixed by microsoft, but nevertheless we had to deal with it...

Actually, you can as well use Object.assign()...

Docs: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Further examples: https://googlechrome.github.io/samples/object-assign-es6/

I know it says no IE, but i tried it on my IE11 and it works...

Guntram
  • 961
  • 14
  • 19
  • 1
    I had an issue using angular.copy() in the object was "hashKey" and the comparison was mistaken. Object.asign() solved an issue. – Tomasz Waszczyk Jun 25 '18 at 11:20