proto

functionMethods

declaration
 functionMethods 

var functionMethods = module.exports = {
    makeFunction: makeFunction,
    partial: partial,
    partialRight: partialRight,
    memoize: memoize,
    delay: delay,
    defer: defer,
    delayed: delayed,
    deferred: deferred,
    deferTicks: deferTicks,
    delayMethod: delayMethod,
    deferMethod: deferMethod,
    debounce: debounce,
    throttle: throttle,
    once: once,
    waitFor: waitFor,
    not: not
};


var slice = Array.prototype.slice;

makeFunction

function
 makeFunction() 

Option name Type Description
name String

new function name

arg1, String

arg2, ... the names of function parameters

funcBody String

function body

return Function

Similarly to Function constructor creates a function from code.
Unlike Function constructor, the first argument is a function name

function makeFunction(arg1, arg2, funcBody) {
    var name = this
        , count = arguments.length - 1
        , funcBody = arguments[count]
        , func
        , code = '';
    for (var i = 0; i < count; i++)
        code += ', ' + arguments[i];
    code = ['func = function ', name, '(', code.slice(2), ') {\n'
                , funcBody, '\n}'].join('');
    eval(code);
    return func;
}

partial

function
 partial() 

Option name Type Description
self Function

Function to be applied

arguments List

Arguments after self will be prepended to the original function call when the partial function is called.

return Function

Creates a function as a result of partial function application with the passed parameters.

function partial() { // , ... arguments
    var func = this;
    var args = slice.call(arguments);
    return function() {
        return func.apply(this, args.concat(slice.call(arguments)));
    };
}

partialRight

function
 partialRight() 

Option name Type Description
self Function

Function to be applied

arguments List

Arguments after self will be appended on the right to the original function call when the partial function is called.

return Function

Creates a function as a result of partial function application with the passed parameters, but parameters are appended on the right.

function partialRight() { // , ... arguments
    var func = this;
    var args = slice.call(arguments);
    return function() {
        return func.apply(this, slice.call(arguments).concat(args));
    };
}

memoize

function
 memoize() 

Option name Type Description
self Function

function to be memoized

hashFunc Function

optional hash function that is passed all function arguments and should return cache key.

limit Integer

optional maximum number of results to be stored in the cache. 1000 by default.

return Function

memoized function

Creates a memoized version of the function using supplied hash function as key. If the hash is not supplied, uses its first parameter as the hash.

function memoize(hashFunc, limit) {
    var func = this;
    var cache = {}, keysList = [];
    limit = limit || 1000;

    return function() {
        var key = hashFunc ? hashFunc.apply(this, arguments) : arguments[0];
        if (cache.hasOwnProperty(key))
            return cache[key];

        var result = cache[key] = func.apply(this, arguments);
        keysList.push(key);

        if (keysList.length > limit)
            delete cache[keysList.shift()];

        return result;
    };
}

delay

function
 delay() 

Option name Type Description
self Function

function that execution has to be delayed

wait Number

approximate dalay time in milliseconds

arguments List

optional arguments that will be passed to the function

Delays function execution by a given time in milliseconds.
The context in function when it is executed is set to null.

function delay(wait) { // , arguments
    var args = slice.call(arguments, 1);
    return _delay(this, wait, args);
}

defer

function
 defer() 

Option name Type Description
self Function

function that execution has to be delayed

arguments List

optional arguments that will be passed to the function

Defers function execution (executes as soon as execution loop becomes free)
The context in function when it is executed is set to null.

function defer() { // , arguments
    return _delay(this, 1, arguments);
}

function _delay(func, wait, args, context) {
    return setTimeout(func.apply.bind(func, context || null, args), wait);
}

deferFunc

declaration
 deferFunc 

Same as _.defer, takes first argument as the function to be deferred

var deferFunc = makeProtoFunction(defer);

deferTicks

function
 deferTicks() 

Option name Type Description
self Function

function that execution has to be delayed

ticks Integer

number of times to defer execution

arguments List

optional arguments that will be passed to the function

Defers function execution for times ticks (executes after execution loop becomes free times times)
The context in function when it is executed is set to null.

function deferTicks(ticks) { // , arguments
    if (ticks < 2) return defer.apply(this, arguments);
    var args = repeat.call(deferFunc, ticks - 1);
    args = args.concat(this, slice.call(arguments, 1)); 
    return deferFunc.apply(null, args);
}

delayMethod

function
 delayMethod() 

Option name Type Description
self Object

object to delay method call of

funcOrMethodName Function, String

function or name of method

wait Number

approximate dalay time in milliseconds

arguments List

arguments to pass to method

Works like .delay but allows to defer method call of self which will be the first .delayMethod parameter

function delayMethod(funcOrMethodName, wait) { // , ... arguments
    var args = slice.call(arguments, 2);
    return _delayMethod(this, funcOrMethodName, wait, args);
}

deferMethod

function
 deferMethod() 

Option name Type Description
self Object

object to defer method call of

funcOrMethodName Function, String

function or name of method

arguments List

arguments to pass to method

Works like .defer but allows to defer method call of self which will be the first .deferMethod parameter

function deferMethod(funcOrMethodName) { // , ... arguments
    var args = slice.call(arguments, 1);
    return _delayMethod(this, funcOrMethodName, 1, args);
}

function _delayMethod(object, funcOrMethodName, wait, args) {
    return setTimeout(function() {
        var func = typeof funcOrMethodName == 'string'
                    ? object[funcOrMethodName]
                    : funcOrMethodName;
        func.apply(object, args);
    }, wait);
}

delayed

function
 delayed() 

Option name Type Description
self Function

function which execution has to be deferred

wait Number

approximate dalay time in milliseconds

arguments List

optional arguments that will be passed to the function

return Function

Returns function that will execute the original function wait ms after it has been called
The context in function when it is executed is set to null.
Arguments passed to the function are appended to the arguments passed to delayed.

function delayed(wait) { //, ... arguments
    var func = this
        , args = slice.call(arguments, 1);
    return function() { // ... arguments
        var passArgs = args.concat(slice.call(arguments));
        return _delay(func, wait, passArgs, this);
    };
}

deferred

function
 deferred() 

Option name Type Description
self Function

function which execution has to be deferred

arguments List

optional arguments that will be passed to the function

return Function

Returns function that will execute the original function on the next tick once it has been called
The context in function when it is executed is set to null.
Arguments passed to the function are appended to the arguments passed to deferred.

function deferred() { //, ... arguments
    var func = this
        , args = slice.call(arguments);
    return function() { // ... arguments
        var passArgs = args.concat(slice.call(arguments));
        return _delay(func, 1, passArgs, this);
    };
}

debounce

function
 debounce() 

Option name Type Description
self Function

function that execution has to be delayed

wait Number

approximate dalay time in milliseconds

immediate Boolean

true to invoke funciton immediately and then ignore following calls for wait milliseconds

return Function

Creates a function that will call original function once it has not been called for a specified time

function debounce(wait, immediate) {
    var func = this; // first parameter of _.debounce
    var timeout, args, context, timestamp, result;
    return function() {
        context = this; // store original context
        args = arguments;
        timestamp = Date.now();
        var callNow = immediate && ! timeout;
        if (! timeout)
            timeout = setTimeout(later, wait);
        if (callNow)
            result = func.apply(context, args);
        return result;

        function later() {
            var last = Date.now() - timestamp;
            if (last < wait)
                timeout = setTimeout(later, wait - last);
            else {
                timeout = null;
                if (! immediate)
                    result = func.apply(context, args);
            }
        }
    };
}

throttle

function
 throttle() 

Option name Type Description
self Function

function that execution has to be delayed

wait Number

approximate delay time in milliseconds

options Object

{leading: false} to disable the execution on the leading edge

return Function

Returns a function, that, when invoked, will only be triggered at most once during a given window of time.

function throttle(wait, options) {
    var func = this; // first parameter of _.throttle
    var context, args, result;
    var timeout = null;
    var previous = 0;
    options || (options = {});

    return function() {
        var now = Date.now();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0) {
            clearTimeout(timeout);
            timeout = null;
            previous = now;
            result = func.apply(context, args);
        } else if (!timeout && options.trailing !== false)
            timeout = setTimeout(later, remaining);

        return result;
    };

    function later() {
        previous = options.leading === false ? 0 : Date.now();
        timeout = null;
        result = func.apply(context, args);
    }
}

once

function
 once() 

Call passed function only once

function once() {
    var func = this
        , ran = false
        , memo;
    return function() {
        if (ran) return memo;
        ran = true;
        memo = func.apply(this, arguments);
        func = null;
        return memo;
    };
}

waitFor

function
 waitFor() 

Option name Type Description
self Function

function: if it returns true the callback is executed

callback Function

runs when the condition is true

maxTimeout Number

timeout before giving up (time in milliseconds)

timedOutFunc Function

a function called if timeout is reached

checkInterval Number

time interval when you run the condition function (time in milliseconds), default 50 ms

Execute a function when the condition function returns a truthy value
it runs the condition function every checkInterval milliseconds (default 50)

function waitFor(callback, maxTimeout, timedOutFunc, checkInterval){
    var start = Date.now();
    var condition = this;
    checkInterval = checkInterval || 50;
    var interval = setInterval(testCondition, checkInterval);

    function testCondition() {
        if (condition()) callback();
        else if (Date.now() - start >= maxTimeout)
            timedOutFunc && timedOutFunc();
        else return;
        clearInterval(interval);
    };
}

not

function
 not() 

Option name Type Description
self Function

function to negate

return Function

returns the function that negates (! operator) the result of the original function

function not() {
    var func = this;
    return function() {
        return !func.apply(this, arguments);
    };
}