Skip to content

Instantly share code, notes, and snippets.

@adtaylor
Created November 29, 2011 10:20
Show Gist options
  • Save adtaylor/1404306 to your computer and use it in GitHub Desktop.
Save adtaylor/1404306 to your computer and use it in GitHub Desktop.
Comment pulled from node.js google group 'Useful code for "each" on arrays and objects'
// There is *nothing* wrong with changing prototypes in your own code!
// If you're writing a library or framework or a module that has to
// interface with someone else's code then things are a little different,
// but even then some conservative changes can be safe.
// In particular, it's not hard to implement an Object.prototype.forEach
// that works just like Array.prototype.forEach and is very fast.
// See: https://github.com/creationix/proto/blob/master/lib/proto.js#L23-36
// Since it uses Object.defineProperty, the new prototype is not
// enumerable and won't even break people doing for..in loops over
// objects (which is the *slowest* way to iterate over an object)
// The benefit of changing Object.prototype thusly is you can iterate
// over objects and arrays using the exact same OOP style API. It's
// handy for looping over JSON results, for example.
// If your code does interact with others and they may have a different
// idea about what goes in Object.prototype.forEach, then obviously this
// isn't an option.
// If you control the creation of the objects you want to loop over, then
// simply give them a custom prototype.
// var hash = new Hash(); // Where Hash.prototype has .forEach
// If you don't control the creation of the object, (like results of
// JSON.parse), then it's still very easy, just not using OOP style
// calls.
// You can use underscore or implement your own loop if you don't want
// the extra dependency. I see many people using underscore just for
// each. I often have in my library a function like this:
function forEach(obj, callback, thisObject) {
if (Array.isArray(obj)) return obj.forEach(callback, thisObject);
var keys = Object.keys(obj);
var length = keys.length;
for (var i = 0; i < length; i++) {
var key = keys[i];
callback.call(thisObject, obj[key], key, this);
}
}
// Then to use it, I do:
forEach(obj, function (value, key, obj) {
});
// The idea that prototypes are somehow holy is wrong. Yes, you need to
// be aware they can conflict with others, but they are a tool for really
// elegant tools. Be as conservative as possible, but no more, and you
// should be fine. Just document it so your future self and anyone else
// using the code is aware it's there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment