{"id":16326701,"url":"https://github.com/chrisyip/node-extensions","last_synced_at":"2025-10-25T20:32:08.389Z","repository":{"id":18918679,"uuid":"22137657","full_name":"chrisyip/node-extensions","owner":"chrisyip","description":"Useful properties and methods for node","archived":false,"fork":false,"pushed_at":"2016-06-19T08:08:11.000Z","size":101,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T10:35:45.525Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisyip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-23T08:08:49.000Z","updated_at":"2016-06-15T18:03:10.000Z","dependencies_parsed_at":"2022-08-20T19:00:36.212Z","dependency_job_id":null,"html_url":"https://github.com/chrisyip/node-extensions","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisyip%2Fnode-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisyip%2Fnode-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisyip%2Fnode-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisyip%2Fnode-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisyip","download_url":"https://codeload.github.com/chrisyip/node-extensions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238207648,"owners_count":19434095,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T23:09:19.949Z","updated_at":"2025-10-25T20:32:07.950Z","avatar_url":"https://github.com/chrisyip.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Node Extensions\n\n[![NPM version][npm-image]][npm-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Travis CI][travis-image]][travis-url] [![Coveralls][coveralls-image]][coveralls-url]\n\nExtend Node's `global` object. No dependencies except [semver](https://www.npmjs.org/package/semver).\n\n# Usage\n\n```\nnpm install --save node-extensions\n```\n\nThis package attachs APIs to `global` object (like es5-shim), so what you need to do is just require it once in your project's main file, e.g. `index.js` or `app.js`. That's all.\n\nRecommend to require node extensions on the very top of file.\n\n```js\nrequire('node-extensions')\n\nvar obj = { 0: 'Hello', 1: 'Node', length: 2 }\n\nconsole.log(Array.from(obj).reduce(function (prev, cur) {\n  return prev + ' ' + cur\n}))\n// 'Hello Node'\n\nvar fruits = ['Apple', 'Orange']\n\nif (fruits.isEmpty === false) {\n  // do somethinge\n}\n\n'the great gatsby'.toCapitalCase() // 'the Great Gatsby'\n```\n\n## Browser\n\nPlease use module bundler like Browserify or Webpack:\n\n```\nrequire('node-extensions/browser')\n```\n\n# APIs\n\n## Object\n\n### Methods\n\n#### assign\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-object.assign](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign)\n\n```js\nObject.assign(\n    { type: 'node' },\n    { name: 'node-extensions' }\n)\n// { type: 'node', name: 'node-extensions' }\n```\n\n#### hasProps\n\n```js\nlet obj = {\n  foo: {\n    bar: {\n      baz: 'baz'\n    }\n  }\n}\n\nObject.hasProps(obj, 'foo.bar.baz') // true\nObject.hasProps(obj, 'foo.bar.foobar') // false\n```\n\n#### isObject\n\n```js\nObject.isObject({}) === true\nObject.isObject(new Date) === false\nObject.isObject(/reg/) === false\nObject.isObject(undefined) === false\nObject.isObject(null) === false\n```\n\n#### isNull\n\n```js\nObject.isNull(null) === true\nObject.isNull(undefined) === false\n```\n\n#### isUndefined\n\n```js\nObject.isUndefined(undefined) === true\nObject.isUndefined(null) === false\n```\n\n#### merge\n\nDeep version of `Object#assign()`.\n\n```js\nObject.merge(\n    { project: { type: 'node' } },\n    { project: { name: 'node-extensions' } }\n)\n// { project: { type: 'node', name: 'node-extensions' } }\n```\n\n#### pick\n\nCreates a new object that only contain specific keys.\n\n```js\nlet obj = {\n  foo: 'foo',\n  bar: 'bar',\n  baz: 'baz'\n}\n\nObject.pick(obj, 'foo', 'bar')\nObject.pick(obj, ['foo', 'bar'])\n// { foo: 'foo', bar: 'bar' }\n\nObject.pick(obj, (value, key) =\u003e key.startsWith('ba'))\nObject.pick(obj, (value, key) =\u003e key.startsWith(this.prefix) }, { prefix: 'ba' })\n// { bar: 'bar', baz: 'baz' }\n```\n\n#### props\n\n```js\nlet obj = {\n  foo: {\n    bar: {\n      baz: 'baz'\n    }\n  }\n}\n\nObject.props(obj, 'foo.bar.baz') // 'baz'\nObject.props(obj, 'foo.bar.foobar') // undefined\n```\n\n\n## Array\n\n### Properties\n\n#### first\n\n```js\n[1, 2].first === 1\n[].first === undefined\n[null].first === null\n```\n\n#### isEmpty\n\n```js\n[].isEmpty === true\n[1].isEmpty === false\n[ , ].isEmpty === true\n[null].isEmpty === false\n```\n\n#### last\n\n```js\n[1, 2].last === 2\n[].last === undefined\n[null].last === null\n```\n\n### Methods\n\n#### compact\n\n`compact()`\n\nLike Ruby's [Array#compact()](http://www.ruby-doc.org/core-2.1.3/Array.html#method-i-compact), creates a new array that all undefined and null elements removed, or a new array with all elements that pass the test implemented by the provided function.\n\n`compact(mapfn[, thisArg])` alias of `Array#filter()`.\n\n```js\n[1, , null, 2].compact() // [1, 2]\n\n['foo', 'bar', 1, 2].compact(function (item) {\n    return typeof item === 'string'\n}) // ['foo', 'bar']\n```\n\n#### collect(callback, thisArg)\n\n```js\n[1, undefined, null, 2].collect(item =\u003e item) // [1, null, 2]\n\n['foo', 'bar', 1, 2].collect(item =\u003e {\n  if (String.isString(item)) {\n    return item + 'baz'\n  }\n}) // ['foobaz', 'barbaz']\n```\n\n#### equalTo\n\n`equalTo(target, mapfn, thisArg)`\n\n```js\n[1, 2].equalTo([1, 2]) === true\n['a', 1, true].equalTo(['a', 1, true]) === true\n\n[new Date(2014, 0, 1)].equalTo([new Date(2014, 0, 1)]) === false\n\n[new Date(2014, 0, 1)].equalTo([new Date(2014, 0, 1)], function (a, b) {\n    return a.getTime() === b.getTime()\n}) === true\n```\n\n#### includes\n\n```js\n[1, 2, 3].includes(2) === true\n// Array#contains is an alias of Array#includes\n[1, 2, 3].contains(2) === true\n```\n\n#### insert\n\n```js\nArray.insert(element, position)\n```\n\n```js\nvar arr = [1, 2, 3]\narr.insert(5) // [1, 2, 3, 5]\narr.insert(4, 3) // [1, 2, 3, 4, 5]\n```\n\n#### find \u0026 findIndex\n\n```js\n[1, 2, 3].find(function (item) {\n    return item % 2 === 0\n}) // 2\n\n[1, 2, 3].findIndex(function (item) {\n    return item % 2 === 0\n}) // 1\n```\n\n#### flatten\n\n```js\n[1, [2, [3, [4, { 0: 5, length: 1 }]]]].flatten() // [1, 2, 3, 4, 5]\n```\n\n#### from\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-array.from](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from)\n\nFor now, only support array and array-like object.\n\n```js\nArray.from({ 0: 'a', 1: 'b', length: 2 })\n// [ 'a', 'b' ]\n\nArray.from('abc')\n// [ 'a', 'b', 'c' ]\n\nArray.from(new String('abc'))\n// [ 'a', 'b', 'c' ]\n```\n\n#### isArrayLike\n\n```js\nArray.isArrayLike({ 0: 'a', 1: 'b', length: 2 }) === true\nArray.isArrayLike('abc') === true\nArray.isArrayLike(new String('abc')) === true\n\nArray.isArrayLike({ 0: 'a', 1: 'b' }) === false\nArray.isArrayLike(1) === false\nArray.isArrayLike(true) === false\n\nvar b = new Boolean(true)\nb.length = 4\nArray.isArrayLike(b) === false\n```\n\n#### isEmpty\n\n```js\nArray.isEmpty([]) === true\nArray.isEmpty([ , ]) === true\n```\n\n#### Iterators\n\n`forEach`, `map`, `every`, `some`, `filter`, `reduce`, `reduceRight`, `indexOf`, `lastIndexOf` and 'slice' are overrided for performance concerned.\n\nThe new methods are faster than built-in methods. By overriding the built-in methods, the general performances of using built-in methods should be improved. More details: [benchmarks](https://github.com/chrisyip/node-extensions/blob/master/bench/results).\n\n```js\narray.forEach(iterator).map(iterator)\n\n[1, 2, 3].forEachRight(function (item) {\n    console.log(item)\n})\n// 3, 2, 1\n```\n\n#### of\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-array.of](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of)\n\n```js\nArray.of(1);         // [1]\nArray.of(1, 2, 3);   // [1, 2, 3]\nArray.of(undefined); // [undefined]\n```\n\n#### pluck\n\nCreates a collection for property values of path in all elements\n\n```js\nvar members = [{ name: 'John', gender: 'male' }, { name: 'Jane', gender: 'female' }]\nmembers.pluck('name')\n// ['John', 'Jane']\n```\n\n#### remove\n\n```js\nArray.remove(element, startPosition)\n```\n\n```js\nvar arr = ['foo', 'bar', 'foo']\narr.remove('foo', 1) // 'foo'\narr // ['foo', 'bar']\narr.remove('foo', 1) // undefined\narr // ['foo', 'bar']\n```\n\n## Boolean\n\n### Methods\n\n#### isBoolean\n\n`isBoolean(target)`\n\n```js\nBoolean.isBoolean(true) // true\nBoolean.isBoolean(false) // true\nBoolean.isBoolean(new Boolean(true)) // true\nBoolean.isBoolean('true') // false\n```\n\n## String\n\n### Properties\n\n#### isEmpty\n\n```js\n''.isEmpty === true\n'  '.isEmpty === true\n'str'.isEmpty === false\n```\n\n### Methods\n\n#### caseCmp\n\nLike Ruby's [`casecmp`](http://ruby-doc.org/core-2.1.0/String.html).\n\n```js\n'foo'.caseCmp('FOo') // true\n'foo'.caseCmp(new String('foo')) // false\n'foo'.caseCmp('FOo', true) // false\n```\n\n#### endsWith\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-string.prototype.startswith](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith)\n\n```js\n'Hello'.endsWith('o') === true\n'Hello'.endsWith('O') === false\n'Hello'.endsWith('l') === false\n'Hello'.endsWith('l', 4) === true\n```\n\n#### includes\n\n[http://people.mozilla.org//~jorendorff/es6-draft.html#sec-string.prototype.includes](http://people.mozilla.org//~jorendorff/es6-draft.html#sec-string.prototype.includes)\n\n```js\n'str'.includes('t') === true\n'str'.includes('sub') === false\n'substr'.includes('sub', 1) === false\n// String#contains availables as an alias of String#includes\n'str'.contains('t') === true\n```\n\n#### isEmpty\n\n```js\nString.isEmpty('') === true\nString.isEmpty(' ') === true\n```\n\n#### isString\n\n```js\nString.isString('str') === true\nString.isString(new String('str')) === true\nString.isString(true) === false\n```\n\n#### interpolate\n\n```js\n'Good morning, ${title} #{lastname}.'.interpolate({\n    title: 'Mr.',\n    lastname: 'Smith'\n})\n'Good morning, ${0} #{2}.'.tpl(['Mr.', 'John', 'Smith'])\n'Good morning, ${0} #{2}.'.template('Mr.', 'John', 'Smith')\n// all outputs 'Good morning, Mr. Smith.'\n```\n\nYou can use `$` and `#` for defining parameters.\n\nAliases: `String#tpl()` \u0026 `String#template()`\n\n#### padStart / padEnd\n\n```js\n'foo'.padStart(10, 'bar') // barbarbfoo\n'foo'.padEnd(10, 'bar') // foobarbarb\n```\n\n#### repeat\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-string.prototype.repeat](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat)\n\n```js\n'*'.repeat(5) === '*****'\n```\n\n#### startsWith\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-string.prototype.startswith](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith)\n\n```js\n'Hello'.startsWith('H') === true\n'Hello'.startsWith('h') === false\n'Hello'.startsWith('e') === false\n'Hello'.startsWith('e', 1) === true\n```\n\n#### toCamelCase\n\n[http://stackoverflow.com/a/10425344](http://stackoverflow.com/a/10425344)\n\n```js\n'hello   world'.toCamelCase() === 'helloWorld'\n'hello----world'.toCamelCase() === 'helloWorld'\n'hello___world'.toCamelCase() === 'helloWorld'\n'hello_world'.toCamelCase() === 'helloWorld'\n'hello.world'.toCamelCase() === 'hello.world'\n'hello.nodejs   world'.toCamelCase() === 'hello.nodejsWorld'\n\n// Make first letter camel cased\n'hello   world'.toCamelCase(true) === 'HelloWorld'\n'hello----world'.toCamelCase(true) === 'HelloWorld'\n'hello___world'.toCamelCase(true) === 'HelloWorld'\n'hello_world'.toCamelCase(true) === 'HelloWorld'\n'hello.world'.toCamelCase(true) === 'Hello.world'\n'hello.nodejs   world'.toCamelCase(true) === 'Hello.nodejsWorld'\n```\n\n#### toCapitalCase\n\n```js\n'hello world'.toCapitalCase() === 'Hello World'\n'hello-world'.toCapitalCase() === 'Hello-world'\n'the great gatsby'.toCapitalCase() === 'the Great Gatsby'\n```\n\n**Note: I'm not a native speaker of English, use it at your own risk. Any contributions would be appreciated.**\n\n## Function\n\n### Methods\n\n#### isCallable\n\n[http://people.mozilla.org/\\~jorendorff/es6-draft.html#sec-iscallable](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-iscallable)\n\n```js\nfunction fn () {}\nFunction.isCallable(fn) === true\n\nvar obj = { call: function () {} }\nFunction.isCallable(obj) === true\n\nFunction.isCallable(Date) === true\n```\n\n#### isFunction\n\n```js\nFunction.isFunction(function () {}) === true\nFunction.isFunction({}) === false\n```\n\n**Symbol is not supported.**\n\n## Number\n\n### Methods\n\n#### isFloat\n\n```js\nNumber.isFloat(1.1) === true\nNumber.isFloat(-1.1) === true\n\nNumber.isFloat(1) === false\nNumber.isFloat(-1) === false\nNumber.isFloat(0) === false\nNumber.isFloat(1.0) === false\nNumber.isFloat('') === false\nNumber.isFloat('0') === false\nNumber.isFloat(NaN) === false\nNumber.isFloat(true) === false\n```\n\n#### isInteger\n\n[http://www.ecma-international.org/ecma-262/6.0/#sec-number.isinteger](http://www.ecma-international.org/ecma-262/6.0/#sec-number.isinteger)\n\n```js\nNumber.isInteger(1) === true\nNumber.isInteger(-1) === true\nNumber.isInteger(0) === true\nNumber.isInteger(1.0) === true\n\nNumber.isInteger(1.1) === false\nNumber.isInteger('') === false\nNumber.isInteger('0') === false\nNumber.isInteger(NaN) === false\nNumber.isInteger(true) === false\n```\n\n# Notes\n\n## Overriding Properties\n\nDue to the limitation of `Object.defineProperty`, you have to use it when overriding properties:\n\n```js\nvar s = ''\ns.isEmpty = 'hello'\ns.isEmpty // true\n\nObject.defineProperty(String.prototype, 'isEmpty', {\n    value: 'hello'\n})\n\ns.isEmpty // 'hello'\n```\n\n[npm-url]: https://npmjs.org/package/node-extensions\n[npm-image]: http://img.shields.io/npm/v/node-extensions.svg?style=flat-square\n[daviddm-url]: https://david-dm.org/chrisyip/node-extensions\n[daviddm-image]: http://img.shields.io/david/chrisyip/node-extensions.svg?style=flat-square\n[travis-url]: https://travis-ci.org/chrisyip/node-extensions\n[travis-image]: http://img.shields.io/travis/chrisyip/node-extensions.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/chrisyip/node-extensions\n[coveralls-image]: http://img.shields.io/coveralls/chrisyip/node-extensions.svg?style=flat-square\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisyip%2Fnode-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisyip%2Fnode-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisyip%2Fnode-extensions/lists"}