0
function outerFunction(x){
    return function(y){
        x=x+1;
        console.log(x+y);
    }
}
var myVal = new Number(2); //myVal is an object
console.log(myVal); //prints Number{[[PrimitiveValue]]: 2}

var innerFunction  = outerFunction(myVal); //I'm passing myVal obj
innerFunction(10)   //13
innerFunction(10)   //14
innerFunction(10)   //15

console.log(myVal);  //prints Number{[[PrimitiveValue]]: 2} instead of 5?

I expected the last console.log to print Number{[[PrimitiveValue]]: 5}, since I passed myVal object to the outerFunction and in JS objects are passed by reference, why it didn't print 5?

5
  • Re: "in JS objects are passed by reference": That's not true (as your code demonstrates). Commented May 29, 2016 at 5:37
  • @ruakh I changed my code to var myObj = {a:2} and passed myObj to the outerfunction..and did x.a = x.a +1 ; and console.log indeed changed to {a:5} which confirms objects are passed by reference Commented May 29, 2016 at 5:43
  • @ruakh Objects are passed as a copy of a reference, so you have to distinguish between mutation and reassignment Commented May 29, 2016 at 6:00
  • @WildWidow: That's not what "pass by reference" means. Yes, there's only one object (unlike in, say, C++, where the function would get a copy of the object); but the variables themselves are distinct. (Don't feel bad; this is actually a really common source of confusion.) Commented May 29, 2016 at 8:38
  • (In C++ terms: in JavaScript you only ever have an implicit pointer to each object; there's no way to refer to an object directly, nor any way to take an explicit pointer. So the function has a distinct pointer to the same object. It's similar to pass-by-reference, until you try to reassign the local variable and find that this only has local effect.) Commented May 29, 2016 at 8:43

1 Answer 1

3

Simple explanation using console.log (do check what javascript prints in console in this case):

function outerFunction(x){

    return function(y){

        console.log("type of x", typeof x); 
        console.log("value x:",x);
        console.log("value y:",y);

        x=x+1;
        console.log(x+y);
    }

}


var myVal = new Number(2); //myVal is an object
console.log(myVal); //prints Number{[[PrimitiveValue]]: 2}

var innerFunction  = outerFunction(myVal); //I'm passing myVal obj
innerFunction(10)   //13
innerFunction(10)   //14
innerFunction(10)   //15

console.log("type of myval",typeof myVal);

console.log(myVal);  //prints Number{[[PrimitiveValue]]: 2} instead of 5?// 

Here what is happening in your code.

==> Firstly you cannot add two objects in javascript using the + operator. So javascript converts it to a Number or a String (in this case a number as you are passing a number itself, which is a primitive type)

==> The inner function that you are returning has an outer reference of X from the outer function. (because of closures)

==> Each time you increment X, the value of x in the scope of outer function changes but it has now no effect on the global "myVal" variable(type object) as javascript considers the local X as primitive type (explained in the first point, which are passed by value and not by reference)

==> So the global value remains the same and X keeps changing which is accessed by inner function, that is why you see 13,14,15 as answers

Hope it helps

Sign up to request clarification or add additional context in comments.

3 Comments

it is called currying
@Wild This is an insufficient response: myVal isn't a function but an object. Objects are passed by sharing a copy of the reference. The correct evaluation strategy is thus pass by sharing. So the OP's assumption is almost right, that Objects are passed by (a copy of a) reference. With this evaluation strategy you have to distinguish mutation let n = new Number(2); n.x = true; and reassignment let n = new Number(2); n = 3;
@lven , can you elaborate a bit on your point? Also there was a typing error in my point no. 3 which I have corrected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.