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

Reply via email to