Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Calling function second time affects variable from first invocation

I was just experimenting and this got me confused. I don’t see why calling foo two times should affect output of the timeout callback from previous invocation. This code:

let state = {
    age: 0
};
let getState = () => {
     let setState = () => {
        state = {
            age: state.age + 1
        }
    }
    return {
        state,
        setState
    }
}

function foo() {
    let {
        state:st,
        setState
    } = getState();
    replicaUseEffect = () => {
        console.log("replicaUseEffect", st);
    }
    console.log("before", st);

    setState()
    console.log("after", st);


    setTimeout(() => replicaUseEffect(), 1000)
};
foo();

produces following output which I am ok with more or less:

"before", {
  age: 0
}
"after", {
  age: 0
}
"replicaUseEffect", {
  age: 0
}

Now, simply call foo twice instead:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

foo();
foo();

And output is this:

"before", {
  age: 0
}
"after", {
  age: 0
}
"before", {
  age: 1
}
"after", {
  age: 1
}
"replicaUseEffect", {
  age: 1
}
"replicaUseEffect", {
  age: 1
}

Why calling foo two times affect both replicaUseEffect values in the second example and output 1 two times?
I tried also printing inside the console.log with JSON.stringify but result is the same.

>Solution :

The reason that both replicaUseEffect calls output the same value, is that replicaUseEffect has been defined as a global variable, and so the second call of foo replaces the previous version of replicaUseEffect with a new one. And although its code is exactly the same, it lives in a different closure, which has the st local variable of the second execution context of foo.

You don’t have this effect when replicaUseEffect is defined as a local variable:

let state = {
    age: 0
};
let getState = () => {
     let setState = () => {
        state = {
            age: state.age + 1
        }
    }
    return {
        state,
        setState
    }
}

function foo() {
    let {
        state:st,
        setState
    } = getState();
    const replicaUseEffect = () => {
        console.log("replicaUseEffect", st);
    }
    console.log("before", st);

    setState()
    console.log("after", st);


    setTimeout(() => replicaUseEffect(), 1000)
};
foo();
foo();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading