Why You Shouldn't Use Backbone's Built-in Array Functions
Today I ran into an issue that let me dive into the Backbone.js library. Very often developers just use the stuff that is in there because it just works fine, but when it does not do what it is supposed to do the best way is to have a look into the used library and figure out what is going on.
My case was the following:
I had some lines for getting the index of a particular model stored inside of a Backbone collection.
Not very complicated and it worked immediately. I did not really think about it. A colleague came around and pointed me into the direction, that the native Array function indexOf is only supported in IE9 and higher. I changed it to use the particular LoDash/Underscore utility function and it did not work anymore.
So, what was going on? After thinking about it, the idea that a Backbone collection uses the native Array function indexOf does not even make sense. So where does it come from? I checked the code and noticed that Backbone collections implement the Array functions of LoDash/Underscore. I created a JSBin to try this principle myself.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Let us dive into the stuff that goes on inside of the each loop.
This line puts the actual array ( –> this.array ) to this start of this new generated “arguments array” to make it fit into the way LoDash/Underscore functions expect the handed in arguments to be.
And this is the final result. It is an actual call to the origin LoDash/Underscore function in the context of Underscore/LoDash. The context needs to be set to LoDash/Underscore itself, because we don’t know, if the library calls other methods contained in itself. To sum up this line for example of indexOf is similar to:
1 2 3
No magic. but a nice way to make the usability of your objects more convenient.
But there is also a bad part about that. I checked the performance of the origin utility methods and the integrated ones and there is really a huge difference ( check jsperf here ). On my machine the new integrated functions are around 75% (!) percent slower ( tested in Firefox, Chrome and Opera ). 75% is really way too much for convenience.
The reason for that difference is probably the needed context binding for the integrated utility functions to provide the LoDash/Underscore context inside of the function itself. But that is only guessing. ;)
No matter what, for me is clear that I will use the original utility functions instead of the integrated ones.
Thx for reading. Any ideas on that are really welcome. :)