views:

482

answers:

4

Us Mootoolers and Prototypers (what few are on this site) usually carry around a handy toolbox of functions we have created (or borrowed) that we implement on native javascript objects to make our lives a little easier. I wanted get a list together of very helpful prototyped functions, but only ones that are implemented on native objects (ie String.implement({... in mootools).

So, what are your favorites?


PS: I included both mootools and prototype as a function written for one library is pretty easily ported to the other.

PPS: I know the arguments for/against prototyping native javascript objects, I would prefer to avoid that discussion here.

+1  A: 

Here are some of my favorites for mootools.

String functions

String.implement({

    //easy way to test if a string contains characters (input.value.isEmpty())
    isEmpty : function() {
     return (!this.test(/\w+/));
    },

    //add ellipses if string length > len
    ellipse : function(len) {
     return (this.length > len) ? this.substr(0, len) + "..." : this;
    },

    //finds all indexOf occurrences
    indexesOf : function(val) {
     var from = 0;
     var indexes = [];
     while (0 <= from && from < this.length) {
      var idx = this.indexOf(val, from);
      if (idx >= 0) {
       indexes.push(idx);
      } else {
       break;
      }
      from = idx+1;
     }
     return indexes;
    }
});

Array functions

Array.implement({

    //compare two arrays to see if they are identical
    compare : function(arr, strict) {
     strict = strict || false;
     if (this.length != arr.length)    return false;

     for (var i = 0; i < this.length; i++) {
      if ($type(this[i]) == "array") {
       if (!this[i].compare(arr[i])) return false;
      }
      if (strict) {
       if (this[i] !== arr[i])  return false;
      } else {
       if (this[i] != arr[i])  return false;
      }
     }
     return true;
    },

    //remove non-unique array values
    unique : function() {
     for(var i = 0; i< this.length; i++) {
      var keys = this.indexesOf(this[i]);
      while (keys.length > 1) {
       this.splice(keys.pop(), 1);
      }
     }
     return this;
    },

    //same as array.unshift, except returns array instead of count
    //good for using inline... array.lpush('value').doSomethingElse()
    lpush : function() {
     for (var i = arguments.length -1 ; i >= 0; i--){
      this.unshift(arguments[i]);
     }
     return this;
    },

    //get all indexes of an item in an array
    indexesOf : function(item) {
     var ret = [];
     for (var i = 0; i < this.length; i++) {
      if (this[i] == item) ret.push(i);
     }
     return ret;
    }
});
tj111
A: 
//taken from http://prototype.lighthouseapp.com/projects/8886/tickets/351-new-swap-method-for-elements
Element.addMethods({
  swap: (function() {
    if ('swapNode' in document.documentElement)
      return function(element, other) {
        return $(element).swapNode($(other));
      };
    return function(element, other) {
       element = $(element);
       other = $(other);
       var next = other.nextSibling, parent = other.parentNode;
       element.parentNode.replaceChild(other, element);
       return parent.insertBefore(element, next);
    };
  })()
 });


// extend the array object to support indexed insertions
// submitted at http://prototype.lighthouseapp.com/projects/8886-prototype/tickets/356-arrayinsert
Array.prototype.insert=function(element,where) {
    var slice1=this.slice(0,where);
    var slice2=this.slice(where);

    return new Array.concat(slice1,element,slice2);
};


//extend the array object to support searching thrtough indexed arrays
// if returnIndex is true, then return the keyName, else return the value from that cell
Array.prototype.nextValue=function(startIndex,returnIndex) {
    for(var i=startIndex+1;i<this.length;i++){
     if(this[i]){
      return (returnIndex?i:this[i]);
     }
    }
    return null;
};


//extend the array object to support searching thrtough indexed arrays
// if returnIndex is true, then return the keyName, else return the value from that cell
Array.prototype.prevValue=function(startIndex,returnIndex) {
    for(var i=startIndex-1;i>=0;i--){
     if(this[i]){
      return (returnIndex?i:this[i]);
     }
    }
    return null;
};
Quamis
A: 

I haven't really been developing with neither Prototype nor Mootools, but I guess the following things would be useful in those frameworks too.

Replacement for native Math.round() that takes optional second parameter that specifies the precision:

Math.round(3.1415, 2); // 3.14

not() method for functions to get a negated predicate:

var even = function(x){ return x % 2 === 0; };
var odd = even.not();
even(2); // true
odd(2); // false

But most useful things are the ones, that I would add to Object.prototype if that would be a safe way to do it, so instead I have some global functions to iterate over object properties.

objMap() that works like Array.map() but for objects:

// returns {a:2, b:4, c:6}
objMap({a:1, b:2, c:3}, function(value) {
  return value*2;
});

objValues() and objKeys() to get array of property names or values from object:

objValues({a:1, b:2, c:3}); // [1, 2, 3]
objKeys({a:1, b:2, c:3}); // ["a", "b", "c"]

And of course objReduce() to do almost anything imaginable...

Implementation details have been left as an excercise for the reader :-)

Rene Saarsoo
objMap, objValues and objKeys are all implemented in MooTools (via Hash class).
Mike Korobov
A: 

I like how the property is checked before creation, to avoid overwriting native properties.

if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(){ ... };
}
Luca Matteis