Каковы ваши любимые прототипы собственных прототипов Mootools/Prototype?

Us Mootoolers и Prototypers (что мало кто на этом сайте) обычно несут вокруг удобного инструментария функций, которые мы создали (или заимствовали), которые мы реализуем на собственных объектах javascript, чтобы сделать нашу жизнь немного легче. Я хотел получить список вместе очень полезных прототипированных функций, но только те, которые реализованы на собственных объектах (т.е. String.implement({... в mootools).

Итак, каковы ваши фавориты?


PS: я включил как mootools, так и прототип в качестве функции, написанной для одной библиотеки, довольно легко переносится на другую.

PPS: Я знаю аргументы для/против прототипирования собственных javascript-объектов, я бы предпочел избежать этого обсуждения здесь.

Ответ 1

Я продолжил то, что началось tj111, вот мое небольшое дополнение:

Array.implement({
    //calculate the sum of all integers
    sum: function() {
        var sum = this.reduce(function(a, b) {
            return a + b;
        });
        return sum;
    }
});

Ответ 2

Вот некоторые из моих любимых для mootools.

Строковые функции

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.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;
    }
});

Ответ 3

//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;
};

Ответ 4

Я не разрабатывал ни прототип, ни Mootools, но я думаю, что в этих рамках также было бы полезно следующее.

Замена для встроенного Math.round(), который принимает необязательный второй параметр, который задает точность:

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

not() метод для функций, чтобы получить предикат с отрицанием:

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

Но самые полезные вещи - это те, которые я бы добавил к Object.prototype, если бы это был безопасный способ сделать это, поэтому вместо этого у меня есть некоторые глобальные функции для итерации над свойствами объекта.

objMap(), который работает как Array.map(), но для объектов:

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

objValues ​​() и objKeys(), чтобы получить массив имен свойств или значений из объекта:

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

И, конечно, objReduce() делать практически все, что только можно вообразить...

Детали реализации были оставлены в качестве упражнения для читателя: -)

Ответ 5

Мне нравится, как свойство проверяется перед созданием, чтобы не перезаписывать собственные свойства.

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