Object.keys incorrectly iterates over non-enumerable `constructor` properties and friends in IE < 9. #198

Open
jdalton opened this Issue Jan 4, 2014 · 5 comments

Projects

None yet

2 participants

@jdalton
Contributor
jdalton commented Jan 4, 2014
function Foo() {}
Object.keys(Foo.prototype);
// should be [], but is ['constructor']

Object.keys(Boolean.prototype);
 // should be [], but is ['toString', 'valueOf', 'constructor']
@ljharb ljharb was assigned Jan 4, 2014
@ljharb
Member
ljharb commented Jan 4, 2014

There's already explicit code that checks for this - https://github.com/es-shims/es5-shim/blob/master/es5-shim.js#L652-L690 - I'm not sure where the flaw is.

@ljharb ljharb added a commit to ljharb/es5-shim that referenced this issue Jan 4, 2014
@ljharb ljharb Adding some Object.keys tests for IE < 9, related to #198 fa593e3
@jdalton
Contributor
jdalton commented Jan 4, 2014

The issue is it's iterating over the 7 properties without checking if it's a prototype object or those prototypes belonging to other built-ins.

@ljharb
Member
ljharb commented Jan 5, 2014

So you're saying that the hasDontEnum bug (that explicitly adds these keys) shouldn't apply to native prototypes? ie, native prototypes should be explicitly blacklisted from this behavior?

@jdalton
Contributor
jdalton commented Jan 5, 2014

Different built-in prototypes have different non-enumerable props. I handle this in lodash via a map of non-enumerable props for builtins and then in its method template to check (weakly) if an object is a prototype object.

@jdalton
Contributor
jdalton commented Jan 5, 2014

The reason I special case String.prototype and Error.prototype checks is because in IE < 9 the String.prototype returns [[object Object]] instead of [[object String]] and Error.prototype returns [[object Object]] instead of [[object Error]] when running them through toString.call. I could probably be more generic there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment