41

What are your most useful, most practical methods that extends built-in JavaScript objects like String, Array, Date, Boolean, Math, etc.?

String

Array

Date

Note : Please post one extended method per answer.

Community
  • 1
  • 1
Canavar
  • 47,715
  • 17
  • 91
  • 122

21 Answers21

41

String Replace All :

String.prototype.replaceAll = function(search, replace)
{
    //if replace is not sent, return original string otherwise it will
    //replace search string with 'undefined'.
    if (replace === undefined) {
        return this.toString();
    }

    return this.replace(new RegExp('[' + search + ']', 'g'), replace);
};

var str = 'ABCADRAE';
alert(str.replaceAll('A','X')); // output : XBCXDRXE
Rafael Merlin
  • 2,517
  • 1
  • 25
  • 31
Canavar
  • 47,715
  • 17
  • 91
  • 122
  • This is a nice enhancement but to make it even better you could add two parameters to the function definition and use them instead of arguments array. This will shorten the code to two lines. Personally I don't see any point of using arguments array if your function doesn't need to accept arbitrary number of arguments. – RaYell Jul 17 '09 at 06:11
  • RaYell, what you said makes sense. Will edit the post. – SolutionYogi Jul 17 '09 at 06:21
  • 3
    Another improvement: if you add any regexp special characters you might get unexpected results. i.e. if you pass '.' as a search string you will replace all the characters. To avoid that change your regex to something like new RegExp('[' + search ']') – RaYell Jul 17 '09 at 06:31
  • 1
    That's a great catch buddy. You should start editing these posts! :) – SolutionYogi Jul 17 '09 at 06:36
  • 2
    @RaYell - that won't work if you want to replace more than one character at a time, e.g. `'foobar'.replaceAll('foo')`. I think it's better to make it clear that a regexp is accepted as the first argument. – harto Jul 17 '09 at 06:42
  • (actually it will work for my example, but hopefully my point makes sense :) – harto Jul 17 '09 at 06:43
  • Awesome, thanks, I like this one.. – Canavar Jul 17 '09 at 06:47
  • 1
    Indeed that may not work correctly if you replace words with that. Then perhaps a better solution would if be to check what type the search parameter is. If it's a string you could then just escape all special characters, if it's a regex (typeof is object) then you could just use it as it is. – RaYell Jul 17 '09 at 06:51
  • Another small fix: if replace is undefined you should return this.toString();, because this contains String object not an actual string. – RaYell Jul 17 '09 at 06:51
  • I posted below another implementation of replaceAll method that correctly handles both string and regular expressions, it uses split and join methods instead of creating regular expressions and doing replaces with them. – RaYell Jul 17 '09 at 07:20
  • This seem to be buggy in some cases.. probably because of unwanted parsing of content as regex –  Apr 29 '16 at 12:53
  • By using square brackets in your RegExp, you are telling it to find any instance of each character in the source, not a match to the whole string. You should use parens, not square brackets. – Zag Oct 24 '18 at 15:58
38

Here's another implementation of String.replaceAll() method

String.prototype.replaceAll = function(search, replace) {
    if (replace === undefined) {
        return this.toString();
    }
    return this.split(search).join(replace);
}

The difference between this one and solution posted here is that this implementation handles correctly regexp special characters in strings as well as allows for word matching

Community
  • 1
  • 1
RaYell
  • 69,610
  • 20
  • 126
  • 152
  • Why would you need to do .toString? If replace is undefined, you are assigning original object back to itself. e.g. string test = "hello"; test = test.replace("hello"); – SolutionYogi Jul 17 '09 at 14:24
  • 1
    If I remove toString() and run this I will get an object not a string. Try using typeof on the returned value (tested in FF & Firebug, don't know if other browsers handle that in different way). – RaYell Jul 17 '09 at 17:51
16
Array.prototype.indexOf = Array.prototype.indexOf || function (item) {
    for (var i=0; i < this.length; i++) {
        if(this[i] === item) return i;
    }
    return -1;
};

Usage:

var list = ["my", "array", "contents"];
alert(list.indexOf("contents"));     // outputs 2
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
Makram Saleh
  • 8,613
  • 4
  • 27
  • 44
  • 4
    This method is implemented in most browsers so you could add an existence check before overwriting something that can be already done. IMO you should wrap this code inside if (Array.prototype.indexOf === undefined) {...} – RaYell Jul 17 '09 at 04:55
  • 1
    RaYell, updated the code not to redefine indexOf if it's already present. – SolutionYogi Jul 17 '09 at 05:50
9

There are a ton of String.prototype functions from James Padolsey

https://github.com/padolsey/string.prototype

These include:

  • camelize
  • contains
  • count
  • enclose
  • extract
  • forEach
  • forEachWord
  • linkify
  • many
  • randomize
  • remove
  • reverse
  • shorten
  • sort
  • toDOM
  • trim
  • wrap
Community
  • 1
  • 1
Jon Erickson
  • 112,242
  • 44
  • 136
  • 174
8

String.format

String.prototype.format = function (values) {

    var regex = /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g;

    var getValue = function (key) {
            if (values == null || typeof values === 'undefined') return null;

            var value = values[key];
            var type = typeof value;

            return type === 'string' || type === 'number' ? value : null;
        };

    return this.replace(regex, function (match) {
        //match will look like {sample-match}
        //key will be 'sample-match';
        var key = match.substr(1, match.length - 2);

        var value = getValue(key);

        return value != null ? value : match;
    });
};

Usage:

alert('Program: {key1} {key2}'.format({ 'key1' : 'Hello', 'key2' : 'World' })); //alerts Program: hello world
Nikhil Agrawal
  • 26,128
  • 21
  • 90
  • 126
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78
  • thats a good one. Would be really cool if it was extended to mimick the C# one where you can specify a context sensitive formatting for dates/numbers/objects eg. String.Format("{0:d}", val) – Darko Jul 17 '09 at 05:04
  • I think Microsoft's ASP.NET Ajax library has string.Format which mimics C#'s string.Format method. – SolutionYogi Jul 17 '09 at 05:08
  • You are right Nosredna, fixed the post. – SolutionYogi Jul 17 '09 at 05:12
7
// left trim
String.prototype.ltrim = function () {
    return this.replace(/^\s+/, '');
}

// right trim
String.prototype.rtrim = function () {
    return this.replace(/\s+$/, '');
}

// left and right trim
String.prototype.trim = function () {
    return this.ltrim().rtrim();
}
RaYell
  • 69,610
  • 20
  • 126
  • 152
5

String Padding :

String.prototype.padLeft = function (length, character) { 
     return new Array(length - this.length + 1).join(character || ' ') + this; 
}
'trial'.padLeft(7, 'X'); // output : 'XXtrial'
'trial'.padLeft(7);      // output : '  trial'



String.prototype.padRight = function (length, character) { 
     return this + new Array(length - this.length + 1).join(character || ' '); 
}
'trial'.padRight(7, 'X'); // output : 'trialXX'
'trial'.padRight(7);      // output : 'trial  '
Canavar
  • 47,715
  • 17
  • 91
  • 122
3

PHP.JS is a very nice effort to port most of PHP's functions to JavaScript. They currently have an extremely impressive list:

Online at: http://phpjs.org/functions/index

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sampson
  • 265,109
  • 74
  • 539
  • 565
3

Function.prototype.bind from the Prototype library.

Similar to call and apply but allows you to return a reference to a function that is called in a particular context instead of executing it immediately. Also allows you to curry parameters. It's so useful that it became a part of ECMAScript 5 and is already being implemented natively in browsers.

Function.prototype.bind = function() {
  var __method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function() {
    var local_args = args.concat(Array.prototype.slice.call(arguments));
    if (this !== window) local_args.push(this);
    return __method.apply(object, local_args);
  }
}
Jimmy
  • 35,686
  • 13
  • 80
  • 98
2

The various list manipulation prototypes are always great. Since you want only one per post, I'll just post foldl, which I discovered via SML (it "folds" the list, left to right, it has a counter part in foldr of course).

Array.prototype.foldl = function(fnc,start) {
    var a = start;
    for (var i = 0; i < this.length; i++) {
        a = fnc(this[i],a);
    }
    return a;
}

Some trivial examples could be:

var l = ["hello" , "world"];
l.foldl(function(i, acc) { return acc+" "+i; }, "") // => returns "hello world"

Sadly, the failure of standard DOM methods to return true arrays makes alot of these such methods rather useless. And if you're using a Lib of some sort, they often define methods like these already (map, filter, exists, etc).

Svend
  • 7,916
  • 3
  • 30
  • 45
1

Date.toMidnight

Date.prototype.toMidnight = function(){ 
  this.setMinutes(0); 
  this.setSeconds(0); 
  this.setHours(0) 
}
seth
  • 36,759
  • 7
  • 60
  • 57
  • 3
    Poorly named, since it modifies the date object, instead of returning a different value like other toX methods. – Miles Jul 17 '09 at 05:06
1

Array contains:

Array.prototype.contains = function(obj) {
    for (var i=0; i < this.length; i++) {
        if(this[i] === obj) return i;
    }
    return -1;
}

Usage:

var arr = [1, 2, 3];
alert(arr.contains(2));

This little helper function tells you if your array contains an object. If it does then the index of the object is returned, otherwise -1 is returned.

Free Friday afternoon tip: don't ever ever ever modify the Object prototype. That would be just asking for a whole world of pain - I learnt this the hard way :)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Darko
  • 38,310
  • 15
  • 80
  • 107
  • 1
    That's the same as Array.indexOf() method posted above. I would suggest going for indexOf since it's already implemented in most browsers. – RaYell Jul 17 '09 at 06:03
  • I think it's fine to modify the object prototype in some circumstances - so long as you aren't developing Yet Another JavaScript Library, that is. It just means you have to be careful when iterating over object members (i.e. use hasOwnProperty) - but of course, you could add a method to the object prototype that handles the iteration for you :) – harto Jul 17 '09 at 06:39
1

Here's the nice extension for the Date object that allows you to format the date very easily. It uses PHP's date syntax so those familiar with PHP will get it in no time. Others have a huge list of possible switches on the site as well. Personally I haven't found easier way to format dates to various formats.

Date Format

RaYell
  • 69,610
  • 20
  • 126
  • 152
1

A collection of functions I use a lot can be found here:

http://svn.asplib.org/asplib1.2/core/string.asp

http://docs.hyperweb.no/objects/String/

Thomas Kjørnes
  • 1,928
  • 1
  • 17
  • 17
1

I have used the Array.Map function outlined by Scott Koon a couple of times.

http://www.lazycoder.com/weblog/2009/08/12/a-simple-map-function-for-plain-javascript-arrays/

Array.prototype.map = function(fn) {
    var r = [];
    var l = this.length;
    for(i=0;i<l;i++)
    {
        r.push(fn(this[i]));
    }
    return r; 
};
JamesEggers
  • 12,885
  • 14
  • 59
  • 86
1

These two are wrappers for inserting and deleting elements from a particular position in an Array because I don't like the name splice.

// insert element at index
Array.prototype.insertAt = function(element, index) {
    this.splice(index, 0, element);
}

// delete element from index
Array.prototype.removeAt = function(index) {
    this.splice(index, 1);
}

Some more useful Array methods to get away from using indexes:

Array.prototype.first = function() {
    return this[0] || undefined;
};

Array.prototype.last = function() {
    if(this.length > 0) {
        return this[this.length - 1];
    }
    return undefined;
};

Array.prototype.max = function(array){
    return Math.max.apply(Math, array);
};

Array.prototype.min = function(array){
    return Math.min.apply(Math, array);
};

Some useful functions from the MooTools library:

Function.delay

Used to execute a function after the given milliseconds have elapsed.

// alerts "hello" after 2 seconds.
(function() {
    alert("hello");
}).delay(2000);    ​

Number.times

Similar to Ruby's times method for numbers, this accepts a function and executes it N times where N is the numbers value.

// logs hello 5 times
(5).times(function() {
    console.log("hello");
});
Anurag
  • 140,337
  • 36
  • 221
  • 257
0

Use the prototype chain like this:

String.prototype.AddWorld = function() { return this+'World' }

"Hello ".AddWorld(); // returns the string "Hello World"
Steve Harrison
  • 121,227
  • 16
  • 87
  • 72
Franck Freiburger
  • 26,310
  • 20
  • 70
  • 95
0
// This replaces all instances of 'from' to 'to' even when
// 'from' and 'to' are similar (i.e .replaceAll('a', 'a '))
String.prototype.replaceAll = function(from, to) {
    var k = this;
    var i = 0;
    var j = from.length;
    var l = to.length;

    while (i <= k.length)
        if (k.substring(i, i + j) == from) {
        k = k.substring(0, i) + k.substring(i).replace(from, to);
        i += l;
    }
    else
        i++;

    return k;
};
Theofanis Pantelides
  • 4,724
  • 7
  • 29
  • 49
  • It is easier to use the 'g' (global match) flag and do a regular replace. `"abaababa".replace(/a/g, "c") => "cbccbcbc"` – Chetan S Feb 26 '10 at 20:49
0

This is a prototype function for capitalizing a string:

String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}
shasi kanth
  • 6,987
  • 24
  • 106
  • 158
0

Use something like the underscore.js library or for Angular use lodash library.

rupakg
  • 510
  • 4
  • 7
0

There is a nice article at http://maiaco.com/articles/js/missingArrayFunctions.php describing six helpful functions to add to the Array prototype. The functions are linearSearch (same as indexOf given in another answer), binarySearch, retainAll, removeAll, unique, and addAll. The article also includes the JavaScript code for each of the six functions and example code showing how to use them.

Barzee
  • 897
  • 3
  • 15
  • 30