DEV Community

Cover image for Additional JS Prototype Functions
yathink3
yathink3

Posted on • Updated on

Additional JS Prototype Functions

Additional useful library functions like string.toCapitalize(),
string.searchIncludes(), string.camelToTitle(), array.filterMap(), array.forAsyncSerial(), array.forAsyncParallel(), array.arrayToTree(), array.treeToArray(). which you can take benifits of this methods.

const protoTypeDefine = (dataType, name, value) => {
  if (!dataType || !name || !value || !dataType['prototype']) return;
  Object.defineProperty(dataType['prototype'], name, { enumerable: false, value });
};

protoTypeDefine(String, 'toCapitalize', function (value) {
  if (this === '') return '';
  if (value === undefined || value === false) return this.charAt(0).toUpperCase() + this.slice(1);
  return this.replace(/(^\w{1})|(\s+\w{1})/g, l => l.toUpperCase());
});

protoTypeDefine(String, 'searchIncludes', function (value) {
  if (!value) return true;
  return this.toLowerCase().includes(value.trim().toLowerCase());
});

protoTypeDefine(String, 'camelToTitle', function () {
  if (this === '') return '';
  return this.replace(/[0-9]{2,}/g, m => ` ${m} `)
    .replace(/[^A-Z0-9][A-Z]/g, m => `${m[0]} ${m[1]}`)
    .replace(/[A-Z][A-Z][^A-Z0-9]/g, m => `${m[0]} ${m[1]}${m[2]}`)
    .replace(/[ ]{2,}/g, m => ' ')
    .replace(/\s./g, m => m.toUpperCase())
    .replace(/^./, m => m.toUpperCase())
    .trim();
});

protoTypeDefine(Array, 'filterMap', function (fn = null) {
  if (typeof fn !== 'function') return this;
  return this.reduce((acc, item, i) => {
    const value = fn(item, i, this);
    if (value === false || value === undefined) return acc;
    else return [...acc, value];
  }, []);
});

protoTypeDefine(Array, 'forAsyncSerial', async function (fn = null) {
  let result = [];
  for (let i = 0; i < this.length; i++) {
    if (typeof fn !== 'function') result[i] = await this[i];
    else result[i] = await fn(this[i], i, this);
  }
  return result;
});

protoTypeDefine(Array, 'forAsyncParallel', async function (fn = null) {
  if (typeof fn !== 'function') return await Promise.all(this);
  return await Promise.all(this.map(fn));
});

protoTypeDefine(Array, 'arrayToTree', function (id = null, link = 'parentId') {
  return this.filterMap(item => {
    if (!(id === null ? !this.some(ele => ele.id === item[link]) : item[link] === id)) return;
    return { ...item, children: this.arrayToTree(item.id, link) };
  });
});

protoTypeDefine(Array, 'treeToArray', function (key = 'children') {
  return this.reduce((acc, curr) => {
    const newArr = (curr[key] || []).treeToArray(key);
    return [...acc, ...newArr].map(({ [key]: child, ...ele }) => ele);
  }, this);
});

Enter fullscreen mode Exit fullscreen mode

Note :

You need to import file without specifying from and also import at root level of your code and make sure imported only once.

import 'utils/prefixUtility';
Enter fullscreen mode Exit fullscreen mode

example code:

const newArr = [1,2,3,4].filterMap((ele) => {
  if(ele % 2 === 0) return;
  return ele * 2;
});

// output of newArr : [2,6]

// simplified code

const newArr = [1,2,3,4].filterMap((ele) => ele % 2 !== 0 && ele * 2);
// output of newArr : [2,6]
Enter fullscreen mode Exit fullscreen mode

and also if you want create new prototype methods you can make use of protoTypeDefine function.

protoTypeDefine(DataType, method_name, function_which_need_to_add);
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
siva_leo profile image
Siva

Great Tips....thank you
Can you publish in TS with types support..

Collapse
 
yathink3 profile image
yathink3

Sure