0
votes

I'm trying to use the Mout.js throttling function in my application.

Here's the code:

/**
 * @version 0.1.0 (2012/11/27)
 */
export default function throttle(fn, delay) {
    let context;
    let timeout;
    let result;
    let args;
    let cur;
    let diff;
    let prev = 0;
    function delayed() {
        prev = Date.now();
        timeout = null;
        result = fn.apply(context, args);
    }
    function throttled() {
        context = this;
        args = arguments;
        cur = Date.now();
        diff = delay - (cur - prev);
        if (diff <= 0) {
            clearTimeout(timeout);
            prev = cur;
            result = fn.apply(context, args);
        } else if (!timeout) {
            timeout = setTimeout(delayed, diff);
        }
        return result;
    }
    return throttled;
}

however, ESLint says the following:

ESLint: Use the rest parameters instead of 'arguments'. (prefer-rest-params)

At the args = arguments; line. I tried looking at the docs for rest-params, but am having trouble figuring out what's going on.

1
throttled(...rest) and args = rest. Assigning the arguments object directly to another variable, especially in sloppy mode, destroys optimization because the arguments object keeps a live list of parameters whenever the named parameters are re-assigned within the body of the function. In strict mode this behavior does not occur, but it still reduces the amount of assumptions the JIT compiler can make about the code when executing, which results in slower code. - Patrick Roberts

1 Answers

1
votes

The arguments object is not a proper array. That ESLint rule encourages you to not use it.

See the docs for arguments to get an idea of the kind of special handling required to work with the arguments object: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

As Patrick said in the comments, the solution is to use rest parameters like this:

function throttled(...rest) {
    context = this;
    args = rest;
    cur = Date.now();
    diff = delay - (cur - prev);
    if (diff <= 0) {
        clearTimeout(timeout);
        prev = cur;
        result = fn.apply(context, args);
    } else if (!timeout) {
        timeout = setTimeout(delayed, diff);
    }
    return result;
}

See the docs for rest parameters for more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters