ES5 has a enumerable flag. Example
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor , pd = getOwnPropertyDescriptor(Object.prototype, "toString"); assert(pd.enumerable === false, "enumerability has the wrong value");
Partial implementation is do-able by having Object.keys
and Object.getOwnPropertyNames
filter out new non-enumerable properties using the shimmed Object.defineProperty
.
This allows for properties to be non enumerable. This clearly means that Example
for (var key in {}) { assert(key !== "toString", "I should never print"); }
This allows us to add properties to say Object.prototype
(Example)
Object.defineProperty(Object.prototype, "toUpperCaseString", { value: function toUpperCaseString() { return this.toString().toUpperCase(); }, enumerable: false }); for (var key in {}) { assert(key !== "toUpperCaseString", "I should never print"); } console.log(({}).toUpperCaseString()); // "[OBJECT OBJECT]"
How can we emulate this in non-ES5 compliant browsers?
Browser compat table
In this case we care about potentially solving this for
The ES5-shim does not have a solution for this.
The ES5 shim has a solution for most ES5 features that will break your code if it doesn't work.
Is there any black magic that can be done with propiotory IE only APIs? Maybe with VBScript?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With