DEV Community

Cover image for Additional JS Prototype Functions
yathink3
yathink3

Posted on Edited 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