That's great work. I've found myself on your blog a few times in the last few weeks, but I hadn't seen this. I hope you don't mind, I used it to update the example on my blog to:
(function () { var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = true, DontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ], DontEnumsLength = DontEnums.length; for (var k in {toString:null}) hasDontEnumBug = false; Object.keys = Object.keys || function (o) { if (typeof o != "object" && typeof o != "function" || o === null) throw new TypeError("Object.keys called on a non-object"); var result = []; for (var name in o) { if (hasOwnProperty.call(o, name)) result.push(name); } if (hasDontEnumBug) { for (var i = 0; i < DontEnumsLength; i--) { if (hasOwnProperty.call(o, DontEnums[i])) result.push(DontEnums[i]); } } return result; }; })(); You may notice that I sacrificed one of your optimizations for brevity, I'm not sure the benefits would be noticeable in every day use. A library like Prototype may benefit from such an optimization, however. by the way, I noticed that your implementation will have problems when walking the DontEnum properties in Internet Explorer - it looks like you copied and pasted the line of code from the for...in loop to your for loop but forgot to change the variable that was passed in to the iterator function. iterator.call(context || iterator, prop, object[prop]); // References to `prop` should be `DontEnumProperties[i]` Or store DontEnumProperties[i] in a variable for a small optimization. On Oct 21, 9:48 pm, kangax <kan...@gmail.com> wrote: > On Oct 21, 12:11 pm, Andy E <andyearns...@gmail.com> wrote: > > > kangax: I was thinking the same earlier (about caching the > > hasOwnProperty), when I realized that my method incorrectly doesn't > > allow functions to be passed (not sure about Prototype's original > > one). I've updated the function on my blog to: > > > Object.keys = Object.keys || function (o) { > > if (typeof o != "object" && typeof o != "function" || o === null) > > throw new TypeError("Object.keys called on a non-object"); > > > var result = [], hop = Object.prototype.hasOwnProperty; > > That's better, but nothing is stopping from taking it a step further, > aliasing `hasOwnProperty` outside of the method. > > > for (var name in o) { > > if (hop.call(o, name)) > > result.push(name); > > } > > return result; > > > }; > > > Regarding the DontEnum bug, you could work around that by checking > > them explicitly hasOwnProperty outside of the for...in loop. > > Exactly ;) > > See for example `Object.forIn()` that I experimented with a couple of > years ago (wow, how time flies...) > —http://github.com/kangax/protolicious/blob/master/experimental/object... > > Looking at the code now, I would simplify it slightly, but the idea > holds. > > [...] > > -- > kangax -- You received this message because you are subscribed to the Google Groups "Prototype: Core" group. To post to this group, send email to prototype-core@googlegroups.com To unsubscribe from this group, send email to prototype-core-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-core?hl=en