How would I fix these jslint errors?


const noise = () => {
    let canvas, ctx;
    let wWidth, wHeight;
    let noiseData = [];
    let frame = 0;
    let loopTimeout;
    // Create Noise
    const createNoise = () => {
        const idata = ctx.createImageData(wWidth, wHeight);
        const buffer32 = new Uint32Array(idata.data.buffer);
        const len = buffer32.length;
        for (let i = 0; i < len; i++) {
            if (Math.random() < 0.5) {
                buffer32[i] = 0xff000000;
            }
        }
        noiseData.push(idata);
    };
    // Play Noise
    const paintNoise = () => {
        if (frame === 9) {
            frame = 0;
        } else {
            frame++;
        }
        ctx.putImageData(noiseData[frame], 0, 0);
    };
    // Loop
    const loop = () => {
        paintNoise(frame);
        loopTimeout = window.setTimeout(() => {
            window.requestAnimationFrame(loop);
        }, (1000 / 25));
    };
    // Setup
    const setup = () => {
        wWidth = window.innerWidth;
        wHeight = window.innerHeight;
        canvas.width = wWidth;
        canvas.height = wHeight;
        for (let i = 0; i < 10; i++) {
            createNoise();
        }
        loop();
    };
    // Reset
    let resizeThrottle;
    const reset = () => {
        window.addEventListener("resize", () => {
            window.clearTimeout(resizeThrottle);
            resizeThrottle = window.setTimeout(() => {
                window.clearTimeout(loopTimeout);
                setup();
            }, 200);
        }, false);
    };
    // Init
    const init = (() => {
        canvas = document.getElementById("noise");
        ctx = canvas.getContext("2d");
        setup();
    })();
};
noise();

1: JSLint doesnt recognize multiline arrow functions.
2: using commas to indicate multiple variable declarations isnt supported by default. Check the “Multiple vars” box at the bottom.
3: JSlint wants all for loops replaced by other looping constructs.. again, there’s a checkbox at the bottom for allowing “for statements”.

2 Likes

TBH, as @m_hutley sort of pointed out the best way to fix this is to stop using JSLint and upgrade to ESLint.

3 Likes

Here’s how you would fix them.

Expected ‘function’ and instead saw ‘=>’.

Arrow notation should only be used for one-liners of code. So use a function here instead.

// const noise = () => {
function noise() {
    ...
// };
}

We should do that for each of the affected functions, such as createNoise, paintNoise, loop, setup, reset, init.

Expected ‘;’ and instead saw ‘,’.

Packing multiple declarations together on one line allows problems to occur.
Use separate lines for variable declaration. If those separate lines result in too many variables, that’s a good indication that the function is doing too many things and need to be split up.

    // let canvas, ctx;
    let canvas;
    let ctx;
    // let wWidth, wHeight;
    let wWidth;
    let wHeight;

While that works, it’s better if const is used instead for things that don’t change.

Move the canvas and ctx declarations out of the init function, and up to where the variables are declared.

    // let canvas;
    const canvas = document.getElementById("noise");
    // const ctx;
    const ctx = canvas.getContext("2d");
    ...
        // canvas = document.getElementById("noise");
        // ctx = canvas.getContext("2d");

And you can do the same with the width and height:

    // let wWidth;
    const wWidth = window.innerWidth;
    // let wHeight;
    const wHeight = window.innerHeight;
    ...
        // wWidth = window.innerWidth;
        // wHeight = window.innerHeight;

That then gives you some nice const statements near the top of the code:

    const canvas = document.getElementById("noise");
    const ctx = canvas.getContext("2d");
    const wWidth = window.innerWidth;
    const wHeight = window.innerHeight;
    const noiseData = [];

Unexpected ‘for’.

        for (let i = 0; i < len; i++) {

Here we are supposed to use a forEach method instead.

        // const len = buffer32.length;
        // for (let i = 0; i < len; i++) {
        buffer32.forEach(function (ignore, i, buffer) {

Expected ‘function’ and instead saw ‘=>’.

        loopTimeout = window.setTimeout(() => {
            window.requestAnimationFrame(loop);
        }, (1000 / 25));

Multi-line statements are not to be used with the arrow notation.
There is only the requestAnimationFrame statement in the above anyway, so remove the braces.

However, when we remove the braces we need to bring the timeout function together on the same line, so move that time function to a separate variable instead.

        // loopTimeout = window.setTimeout(() =>
        //     window.requestAnimationFrame(loop);
        // }, (1000 / 25));
        const frameLoop = () => window.requestAnimationFrame(loop);
        loopTimeout = window.setTimeout(frameLoop, (1000 / 25));

Unexpected ‘for’.

        for (let i = 0; i < 10; i++) {
            createNoise();
        }

Well that’s arbitrary. What’s happening here is that createNoise is used to add another frame of noise data to the noiseData array.

The createNoise function is currently doing two different things, of creating the noise and also pushing it to the array. It should only have one responsibility, so at the end of the createNoise function it can just return the data, so that the loop controls what happens to that data instead.

    function createNoise() {
        ...
        // noiseData.push(idata);
        return idata;
    }
    ...
        for (let i = 0; i < 10; i++) {
            const noise = createNoise();
            noiseData.push(noise);
        }

We can now give the noiseData function 10 arrays, and map over that to remove the need for the for loop.

    let noiseData = new Array(10).fill(0);
    ...
        /* for (let i = 0; i < 10; i++) {
            const noise = createNoise();
            noiseData.push(noise);
        } */
        noiseData = noiseData.map(createNoise);

We can now move that noiseData array down below the noiseData function, and join things together.

    // let noiseData = Array(10).fill(0);
    ...
    const noiseData = Array(10).fill(0).map(createNoise);
    // noiseData = noiseData.map(createNoise);

This function needs a “use strict” pragma.

Place “use strict” inside the noise function.

function noise() {
    "use strict";

This is required until we use modules, which is a preferred coding technique.

Undeclared ‘document’.

We must run this code in a browser:

/*jslint browser */

Unexpected expression ‘++’ in statement position.

++ is responsible for many confusions, so it’s best avoided.

            // frame++;
            frame += 1;

Unused ‘reset’.

That reset function resizes the noise when the window size changes, so we should add that to the init function.

    function init() {
        reset();
        setup();
    }

That’s JSLint happy with the code, so we can make other improvements here now too.

Improve frame increment

We can use the length of the noiseData array to limit the size of the frame counter, using the modulus operator.

        // if (frame === 9) {
        //     frame = 0;
        // } else {
        //     frame++;
        // }
        frame = (frame + 1) % noiseData.length;

That’s it

And we’re left with the much improved code:

function noise() {
    "use strict";
    const canvas = document.getElementById("noise");
    const ctx = canvas.getContext("2d");
    const wWidth = window.innerWidth;
    const wHeight = window.innerHeight;

    function createNoise() {
        const idata = ctx.createImageData(wWidth, wHeight);
        const buffer32 = new Uint32Array(idata.data.buffer);
        const len = buffer32.length;
        buffer32.forEach(function (ignore, i, buffer) {
            if (Math.random() < 0.5) {
                buffer[i] = 0xff000000;
            }
        });
        return idata;
    }

    const noiseData = Array(10).fill(0).map(createNoise);
    let frame = 0;
    let loopTimeout;

    function paintNoise() {
        frame = (frame + 1) % noiseData.length;
        ctx.putImageData(noiseData[frame], 0, 0);
    }

    function loop() {
        const frameLoop = () => window.requestAnimationFrame(loop);
        loopTimeout = window.setTimeout(frameLoop, (1000 / 25));
        paintNoise(frame);
    }

    function setup() {
        canvas.width = wWidth;
        canvas.height = wHeight;
        loop();
    }

    function reset() {
        let resizeThrottle;
        function resizeHandler() {
            window.clearTimeout(resizeThrottle);
            resizeThrottle = window.setTimeout(function () {
                window.clearTimeout(loopTimeout);
                setup();
            }, 200);
        }
        window.addEventListener("resize", resizeHandler, false);
    }

    function init() {
        reset();
        setup();
    }
    init();
}
noise();

The working example can be found at https://jsfiddle.net/qhkLdveg/24/

Edit:

The above code has been updated to fixed in response to the issue reported below.

4 Likes

This one looks faster

Ahh yes, the frameLoop needs to be a function instead.

        // const frameLoop = window.requestAnimationFrame(loop);
        const frameLoop = () => window.requestAnimationFrame(loop);

Done. https://jsfiddle.net/qhkLdveg/24/

I’ll update the previous post about that too.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.