The absorb() method
After reviewing the comments from everyone on the previous post, I’ve come up with the next generation of the absorb() function: the absorb() method. It occurred to me that this function really was begging to be a method of Object. So, without further adieu:
Object.absorb = function (destination /*:Object*/, source /*:Object*/, overwrite /*:Boolean*/) /*:Object*/ {
for (var key in source) {
if (overwrite || typeof destination[key] == "undefined"){
destination[key] = source[key];
}
}
return destination;
}
Object.prototype.absorb = function (source /*:Object*/, overwrite /*:Boolean*/) /*:Object*/ {
return Object.absorb(this, source, overwrite);
}
Yes, there are two versions. The first is a generic that I’ve placed as a method of Object in order to avoid polluting the global scope. This can be used just like the absorb() function I originally wrote about, such as:
Object.absorb(Array.prototype, {
forEach: function () { ... }
});
The second method is inherited by other others (of course, not DOM objects in Internet Explorer), but it allows easier access to the method:
Array.prototype.absorb({
forEach: function () { ... }
});
Also, thanks to the comment from Les, each method now returns the destination object, so calls can be chained together like this:
Array.prototype.absorb({
forEach: function () { ... }
}).absorb({
map : function () { ... }
})
Of course, if you want to ignore the native or already existing methods, just pass in true as the second argument; this causes absorb() to overwrite any existing methods of the same name:
Array.prototype.absorb({
forEach: function () { ... }
}, true);
And that’s about it. Thanks to everyone who contributed comments on the last post. I feel like this function has evolved into a much more useful and usable form.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




3 Comments
Very nice. And knowing you’re completely aware of the "Object.prototype is verboten" post by Erik, you’ve went ahead and offered it anyway as a handy alternative.
It makes for an very elegant looking example with Array.prototype.absorb( forEach ).absorb( map ); (That was pseudo code).
Dustin Diaz on November 8th, 2006 at 12:26 am
I just wanted to add that the Prototype library uses similar Object.extend method.
Les on November 8th, 2006 at 6:33 am
Dustin – I know Object.prototype has fallen out of favor with some developers, but I think it’s just like everything else: when used wisely, it can be incredibly useful.
Les – That’s interesting, but I don’t think of this as a way of "extending" classes via inheritance, I think of this as a way to allow an object to "absorb" functionality that it wants. I still think using prototypical inheritance is the way to go, especially so you can use instanceof.
Nicholas C. Zakas on November 8th, 2006 at 1:08 pm
Comments are automatically closed after 14 days.