The following features of ES5 cannot be shimmed.
The ones you care about
Enumerable properties [ES3]
Object.defineProperty if you define a non-enumerable property on an object then
for..in loops over that object will behave correctly in modern browsers but enumerate over that property in legacy browsers.
This means that code that works in modern browsers, breaks in legacy browsers.
Getters and Setters [oldIE (IE8 works for Host objects)]
There is no generic way to emulate Getters and Setters in oldIE. There are ways of emulating getters and setters in IE abusing VBScript but not in a way that is compliant with
This requires more research as per issue 91
The ones you don't care about
Strict mode [ES3]
Strict mode will throw errors on compliant browsers when you use the "naughty" parts of ES5 non-strict. It will not cause divergent behaviour on legacy browsers.
This means that as long as you test all your code on one modern browser you get all the benefits of strict mode and it being a no-op on legacy browsers has no side effects that you should care about.
This method cannot return the correct value in legacy browsers if you destroy the
Fun.prototype.constructor === Fun link. As long as that "connection" is there, this function will be well behaved. If this link is broken then that's a bug in your code you should fix. This means that in sensible source code
Object.getPrototypeOf is safe.
Is the same as
Object.keys on legacy engines. There is no way to get non-enumerable properties other then knowing their keys. This isn't an issues outside of host objects as there are no common non-enumerable properties on objects you want to get a hold of as an array.
They all return the true value, but they aren't very useful.
Object.defineProperties [ES3, however writable is only broken in oldIE]
configurable flag have no effect in legacy browers. Again however as long as you test in modern browsers it will throw the exception. This means that the no-op in legacy browsers is harmless.
Note that getters and setters as mentioned above are unshimmables that you should care about (and avoid if you want oldIE support)
Another set of methods that will throw exceptions as long as they are tested on modern browsers. This means that they are safe and harmless no-ops on legacy engines and you do not care about that.
The ones that can be shimmed but are not implemented by ES5-shim
This can be shimmed to an extend. But, ES5 shim is not compliant, See issue #79.