zamf
zamf

Reputation: 35

Variable change by inner function

probably there is something I don't understand. I got a function:

function doSmth(counter) {
    counter++
    console.log(counter);
    doSmthElse(counter)
    console.log(counter);
}

function doSmthElse(counter) {
    counter = counter * 10
}
doSmth(30)

as I thought the result in second console.log should be 310 but it is 31. Why the inner function didn't change the value?

Upvotes: 0

Views: 156

Answers (3)

Aurélien Gasser
Aurélien Gasser

Reputation: 3120

In javascript, numbers passed as arguments to functions are passed as value, not as reference.

What this means is that when you pass counter to the doSmthElse function with doSmthElse(counter), you make a copy of the counter variable and pass it to doSmthElse.

In the doSmthElse implementation, when you do counter = counter * 10, it's the copy of the counter that you modify, not the original counter.

An easy way to fix your problem is to return the updated value and assign it back:

function doSmth(counter) {
    counter = doSmthElse(counter);
}

function doSmthElse(counter) {
    return counter * 10;
}

Note that you wouldn't have the issue if you passed an object instead of a number, because objects are reference types. What is passed the doSmthElse is a pointer to the object: it represents the actual object, not a copy of it:

function doSmth() {
    doSmthElse(obj);
    console.log(obj.counter); // counter has been multiplied by 10
}

function doSmthElse(obj) {
    obj.counter = obj.counter * 10;  // this works: we can modify the object
                                     // that "obj" refers to.

    obj = null // this has no effect outside of the current function: it 
               // simply modifies what the variable "obj" refers to in the
               // current function.
}

Upvotes: 4

WitVault
WitVault

Reputation: 24130

In below function you are passing counter to doSmth function. counter is passed by value to doSmth function as it contains the primitive value such as integer, and not the variable itself.

function doSmth(counter) {
    counter++;
    console.log(counter);
    doSmthElse(counter); // <------------ passed by value
    console.log(counter);
}

Similarly in below function counter is again passed by value when doSmthElse is called from doSmth function.

function doSmthElse(counter) {
    // scope of doSmthElse starts
    counter = counter * 10;
    // counter is local to doSmthElse, it has nothing to do with doSmth's counter variable.
    // scope of doSmthElse ends
}

Above function does the computation i.e multipling by 10 and assigns to local copy of counter. Since that value is within the lexical scope of doSmthElse and not available in outside scope.

Also since returned counter value from doSmthElse is not reassigned to counter variable nothing is actually changed to counter which resides in scope of doSmth function.

Upvotes: 0

Ankit vadariya
Ankit vadariya

Reputation: 1263

This is happening just because of scope of variables.

1st step you need to understand scope of variables and how can you use your variables.

you need to return value for updating counter variable

You can do it like this

function doSmth(counter) {
    counter++
    console.log(counter);
    counter = doSmthElse(counter)
    console.log(counter);
}

function doSmthElse(counter) {
    return counter = counter * 10
}
doSmth(30)

Upvotes: 1

Related Questions