[![Build status][nix-build-image]][nix-build-url]
[![Windows status][win-build-image]][win-build-url]
![Transpilation status][transpilation-image]
[![npm version][npm-image]][npm-url]
# es5-ext
## ECMAScript 5 extensions
### (with respect to ECMAScript 6 standard)
Shims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind.
It's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board.
When used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims.
### Installation
$ npm install es5-ext
To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)
### Usage
#### ECMAScript 6 features
You can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already).
```javascript
require("es5-ext/array/from/implement");
Array.from("foo"); // ['f', 'o', 'o']
```
You can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not.
```javascript
var aFrom = require("es5-ext/array/from");
aFrom("foo"); // ['f', 'o', 'o']
```
If you want to use shim unconditionally (even if native implementation exists) do:
```javascript
var aFrom = require("es5-ext/array/from/shim");
aFrom("foo"); // ['f', 'o', 'o']
```
##### List of ES6 shims
It's about properties introduced with ES6 and those that have been updated in new spec.
- `Array.from` -> `require('es5-ext/array/from')`
- `Array.of` -> `require('es5-ext/array/of')`
- `Array.prototype.concat` -> `require('es5-ext/array/#/concat')`
- `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')`
- `Array.prototype.entries` -> `require('es5-ext/array/#/entries')`
- `Array.prototype.fill` -> `require('es5-ext/array/#/fill')`
- `Array.prototype.filter` -> `require('es5-ext/array/#/filter')`
- `Array.prototype.find` -> `require('es5-ext/array/#/find')`
- `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')`
- `Array.prototype.keys` -> `require('es5-ext/array/#/keys')`
- `Array.prototype.map` -> `require('es5-ext/array/#/map')`
- `Array.prototype.slice` -> `require('es5-ext/array/#/slice')`
- `Array.prototype.splice` -> `require('es5-ext/array/#/splice')`
- `Array.prototype.values` -> `require('es5-ext/array/#/values')`
- `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')`
- `Math.acosh` -> `require('es5-ext/math/acosh')`
- `Math.asinh` -> `require('es5-ext/math/asinh')`
- `Math.atanh` -> `require('es5-ext/math/atanh')`
- `Math.cbrt` -> `require('es5-ext/math/cbrt')`
- `Math.clz32` -> `require('es5-ext/math/clz32')`
- `Math.cosh` -> `require('es5-ext/math/cosh')`
- `Math.exmp1` -> `require('es5-ext/math/expm1')`
- `Math.fround` -> `require('es5-ext/math/fround')`
- `Math.hypot` -> `require('es5-ext/math/hypot')`
- `Math.imul` -> `require('es5-ext/math/imul')`
- `Math.log1p` -> `require('es5-ext/math/log1p')`
- `Math.log2` -> `require('es5-ext/math/log2')`
- `Math.log10` -> `require('es5-ext/math/log10')`
- `Math.sign` -> `require('es5-ext/math/sign')`
- `Math.signh` -> `require('es5-ext/math/signh')`
- `Math.tanh` -> `require('es5-ext/math/tanh')`
- `Math.trunc` -> `require('es5-ext/math/trunc')`
- `Number.EPSILON` -> `require('es5-ext/number/epsilon')`
- `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')`
- `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')`
- `Number.isFinite` -> `require('es5-ext/number/is-finite')`
- `Number.isInteger` -> `require('es5-ext/number/is-integer')`
- `Number.isNaN` -> `require('es5-ext/number/is-nan')`
- `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')`
- `Object.assign` -> `require('es5-ext/object/assign')`
- `Object.keys` -> `require('es5-ext/object/keys')`
- `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')`
- `Promise.prototype.finally` -> `require('es5-ext/promise/#/finally')`
- `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')`
- `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')`
- `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')`
- `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')`
- `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')`
- `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')`
- `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')`
- `String.raw` -> `require('es5-ext/string/raw')`
- `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')`
- `String.prototype.contains` -> `require('es5-ext/string/#/contains')`
- `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')`
- `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')`
- `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')`
- `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')`
- `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')`
#### Non ECMAScript standard features
**es5-ext** provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes:
```javascript
Object.defineProperty(Function.prototype, "partial", {
value: require("es5-ext/function/#/partial"),
configurable: true,
enumerable: false,
writable: true
});
Object.defineProperty(Array.prototype, "flatten", {
value: require("es5-ext/array/#/flatten"),
configurable: true,
enumerable: false,
writable: true
});
Object.defineProperty(String.prototype, "capitalize", {
value: require("es5-ext/string/#/capitalize"),
configurable: true,
enumerable: false,
writable: true
});
```
See [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you.
**Important:** Remember to **not** extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine **only** if you're the _owner_ of the global scope, so e.g. in final project you lead development of.
When you're in situation when native extensions are not good idea, then you should use methods indirectly:
```javascript
var flatten = require("es5-ext/array/#/flatten");
flatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4]
```
for better convenience you can turn methods into functions:
```javascript
var call = Function.prototype.call;
var flatten = call.bind(require("es5-ext/array/#/flatten"));
flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]
```
You can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application
```javascript
var util = {};
util.partial = call.bind(require("es5-ext/function/#/partial"));
util.flatten = call.bind(require("es5-ext/array/#/flatten"));
util.startsWith = call.bind(require("es5-ext/string/#/starts-with"));
util.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4]
```
As with native ones most methods are generic and can be run on any type of object.
## API
### Global extensions
#### global _(es5-ext/global)_
Object that represents global scope
### Array Constructor extensions
#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_
[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from).
Returns array representation of _iterable_ or _a