ES5 has a enumerable flag. Example
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
, pd = getOwnPropertyDescriptor(Object.p
If you do care a lot about IE8/IE7 then you can do
for (p in o) {
if (o.hasOwnProperty(p)) { body }
}
There is no real "hack" alternative but this could be a work-around for simple cases
The accepted answer doesn't really work for literals i.e. strings ""
, numbers 3
, or booleans true
You can do it via code-rewriting. Rewrite every use of for (p in o) body
to
for (p in o) {
if (!(/^__notenum_/.test(p) || o['__notenum_' + p])) {
body
}
}
and then you can mark properties not enumerable by defining a __notenum_...
property. To be compatible you would have to tweak the above to make sure that __notenum_propname
is defined at the same prototype level as propname
, and if you use them, overwrite eval
and new Function
to rewrite.
That's basically what ES5/3 does.
Partial.js by Jake Verbaten is the answer to it.
The partial.js is as follows
/* partial non-enumerable property implementation
Adds a flag to a weakmap saying on obj foo property bar is not enumerable.
Then checks that flag in Object.keys emulation.
*/
// pd.Name :- https://github.com/Raynos/pd#pd.Name
var enumerables = pd.Name();
Object.defineProperty = function (obj, name, prop) {
if (prop.enumerable === false) {
enumerables(obj)[name] = true;
}
...
};
Object.keys = function (obj) {
var enumerabilityHash = enumerables(obj), keys = [];
for (var k in obj) {
if (obj.hasOwnProperty(k) && !enumerabilityHash[k]) {
keys.push(k);
}
}
return keys;
};
Object.getOwnPropertyNames = function (obj) {
var keys = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
keys.push(k);
}
}
};
I hope this helps the guys searching for this fix.