Untitled Designs - Blog

Fun With JavaScript

JavaScript

Fun With JavaScript: Replace Array Contents Without Reassigning

 

I came up against this little puzzle the other day. The specifics aren’t important, I’m working with a 3rd party library and in one of their exposed hooks they pass me a reference to an array. I want to completely replace the contents of that array with some of my own stuff, but in such a way that the library’s internal references will also “see” my changes. Simply reassigning my local reference won’t work. To see what I mean, run the code below in a browser:

var external = [1, 2, 3];
var local = external;
// pretend from here on we can only access local, not external

var newStuff = [4, 5, 6];
local = newStuff;
// now read out the contents of external

console.log(external); // outputs [1, 2, 3]

No dice. What I want is to mutate the underlying data structure. And being the nerd that I am, I want a nice clean solution that doesn’t involve a bunch of looping and size-checking. So first off, let’s see if we can empty the underlying array. Turns out that’s pretty easy:

local.length = 0;

Credit where credit is due, I found that little trick here. It’s so elegant I would never have thought of it. Moving on, we could now just loop through the newStuff array and push each of its elements into the now empty local. But that’s no fun, what kind of JavaScript blog post would this be if I didn’t bust out a “prototype” and an “apply”? Remembering that the array push() method takes a variable number of arguments, I came up with a better way:

Array.prototype.push.apply(local, newStuff);

Again, I can’t take full credit. The idea itself was mine, but the inspiration came from this post by John Resig. And that’s it, mission accomplished in two lines of code. Run this in a browser to see for yourself:

var external = [1, 2, 3];
var local = external;
// pretend from here on we can only access local, not external

var newStuff = [4, 5, 6];
local.length = 0;
Array.prototype.push.apply(local, newStuff);

// now read out the contents of external
console.log(external); // outputs [4, 5, 6]

Cute, right?

 

Photo By Dmitry Baranovskiy

Comments are closed.