What is es5-shim?
The es5-shim package is a JavaScript library that provides compatibility shims so that legacy JavaScript engines behave as closely as possible to ECMAScript 5 (ES5). This is particularly useful for supporting older browsers that do not implement all ES5 features natively.
What are es5-shim's main functionalities?
Array methods
Provides ES5 array methods like map, filter, and reduce which might not be available in older JavaScript engines.
[1, 2, 3].map(function(n) { return n + 1; })
Function.prototype.bind
Implements Function.prototype.bind, allowing functions to have their this value and initial arguments pre-set.
var boundFunc = function(a, b) { return a + b; }.bind(null, 1); boundFunc(2);
Object methods
Adds missing Object methods such as keys, which returns an array of a given object's own enumerable property names.
Object.keys({a: 1, b: 2})
String methods
Includes String.prototype methods like trim, which removes whitespace from both ends of a string.
'hello'.trim()
Date methods
Provides shims for Date methods like now, which returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
Date.now()
Other packages similar to es5-shim
core-js
A modular standard library for JavaScript, core-js includes polyfills for ECMAScript up to 2021. It covers more features than es5-shim, including promises, symbols, collections, iterators, typed arrays, and many other features of ECMAScript 2015 and beyond.
babel-polyfill
Part of Babel's suite, babel-polyfill includes a custom regenerator runtime and core-js. This package is more comprehensive than es5-shim as it supports new ES6 features and beyond, making it suitable for applications needing high compatibility with new ECMAScript standards.
es5-shim
es5-shim.js
and es5-shim.min.js
monkey-patch a JavaScript context to
contain all EcmaScript 5 methods that can be faithfully emulated with a
legacy JavaScript engine.
Note: As es5-shim.js
is designed to patch the native Javascript
engine, it should be the library that is loaded first.
es5-sham.js
and es5-sham.min.js
monkey-patch other ES5 methods as
closely as possible. For these methods, as closely as possible to ES5
is not very close. Many of these shams are intended only to allow code
to be written to ES5 without causing run-time errors in older engines.
In many cases, this means that these shams cause many ES5 methods to
silently fail. Decide carefully whether this is what you want.
Note: es5-sham.js
requires es5-shim.js
to be able to work properly.
Tests
The tests are written with the Jasmine BDD test framework.
To run the tests, navigate to /tests/ , or,
simply npm install
and npm test
.
Shims
Complete tests
- Array.prototype.every (standalone shim)
- Array.prototype.filter
- Array.prototype.forEach (standalone shim)
- Array.prototype.indexOf (standalone shim)
- Array.prototype.lastIndexOf (standalone shim)
- Array.prototype.map (standalone shim)
- Array.prototype.slice
- Array.prototype.some (standalone shim)
- Array.prototype.sort
- Array.prototype.reduce (standalone shim)
- Array.prototype.reduceRight (standalone shim)
- Array.prototype.push
- Array.prototype.join
- Array.isArray
- Date.now
- Date.prototype.toJSON
- Function.prototype.bind
- :warning: Caveat: the bound function has a prototype property.
- :warning: Caveat: bound functions do not try too hard to keep you
from manipulating their
arguments
and caller
properties. - :warning: Caveat: bound functions don't have checks in
call
and
apply
to avoid executing as a constructor.
- Number.prototype.toExponential (standalone shim)
- Number.prototype.toFixed
- Number.prototype.toPrecision
- Object.keys (standalone shim)
- String.prototype.split (standalone shim)
- String.prototype.trim (standalone shim)
- String.prototype.lastIndexOf (standalone shim)
- String.prototype.replace
- Firefox (through v29) natively handles capturing groups incorrectly.
- Date.parse (for ISO parsing)
- Date.prototype.toISOString
- parseInt
- parseFloat
- Error.prototype.toString
- Error.prototype.name
- Error.prototype.message
- RegExp.prototype.toString
Shams
-
:warning: Object.create
For the case of simply "begetting" an object that inherits
prototypically from another, this should work fine across legacy
engines.
:warning: The second argument is passed to Object.defineProperties
which will probably fail either silently or with extreme prejudice.
-
:warning: Object.getPrototypeOf
This will return "undefined" in some cases. It uses __proto__
if
it's available. Failing that, it uses constructor.prototype, which
depends on the constructor property of the object's prototype having
not been replaced. If your object was created like this, it won't
work:
function Foo() {
}
Foo.prototype = {};
Because the prototype reassignment destroys the constructor
property.
This will work for all objects that were created using
Object.create
implemented with this library.
-
:warning: Object.getOwnPropertyNames
This method uses Object.keys, so it will not be accurate on legacy
engines.
-
Object.isSealed
Returns "false" in all legacy engines for all objects, which is
conveniently guaranteed to be accurate.
-
Object.isFrozen
Returns "false" in all legacy engines for all objects, which is
conveniently guaranteed to be accurate.
-
Object.isExtensible
Works like a charm, by trying very hard to extend the object then
redacting the extension.
May fail
-
:warning: Object.getOwnPropertyDescriptor
The behavior of this shim does not conform to ES5. It should
probably not be used at this time, until its behavior has been
reviewed and been confirmed to be useful in legacy engines.
-
:warning: Object.defineProperty
In the worst of circumstances, IE 8 provides a version of this
method that only works on DOM objects. This sham will not be
installed. The given version of defineProperty
will throw an
exception if used on non-DOM objects.
In slightly better circumstances, this method will silently fail to
set "writable", "enumerable", and "configurable" properties.
Providing a getter or setter with "get" or "set" on a descriptor
will silently fail on engines that lack "defineGetter" and
"defineSetter", which include all versions of IE.
https://github.com/es-shims/es5-shim/issues#issue/5
-
:warning: Object.defineProperties
This uses the Object.defineProperty shim.
-
Object.seal
Silently fails on all legacy engines. This should be
fine unless you are depending on the safety and security
provisions of this method, which you cannot possibly
obtain in legacy engines.
-
Object.freeze
Silently fails on all legacy engines. This should be
fine unless you are depending on the safety and security
provisions of this method, which you cannot possibly
obtain in legacy engines.
-
Object.preventExtensions
Silently fails on all legacy engines. This should be
fine unless you are depending on the safety and security
provisions of this method, which you cannot possibly
obtain in legacy engines.
Example of applying ES compatibility shims in a browser project
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.14/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.14/es5-sham.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-sham.min.js"></script>
<script src="other-libs.js"></script>