0

I have been doing some practice example with closures, and I wanted to dive into exactly what is happening in the following situation:

function createClosure(v, obj){
    var numb = v;
    var object = obj;
    return function(){console.log("v = " + numb + "\nobj = " + object.value)}
}

var v = 2;
var obj = {value: 4};
var function1  = createClosure(v, obj);

Situation 1:

When function1(); is run, I get the following result in the console:

v = 2
obj = 4

So far so good. BUT now I tried to modify the variables outside of the closure, and then run function1 again:

Situation 2:

v = 6;
obj.value = 11;
function1();

and I got an interesting result:

v = 2
obj = 11

So when modifying v, that doesn't affect the value of numb inside the closure, but when modifying obj.value it does affect the value of object.value.

QUESTION: Why is this the case? Why the "double" standard so to speak. I initially would have thought that numb would have obtained a copy of v, as well as object obtaining a copy of obj, and hence not being linked with each other, but from the results, that seems not to be the case.

I might guess that it has to do with the way pointers work in JavaScript and it varying for how they interact with variables / objects in closure situations, but that is a guess.

Webeng
  • 7,050
  • 4
  • 31
  • 59
  • It's how pointers work in all programming languages. Pointers "point to" a thing. So copying pointers, enclosing pointers etc. does not change the thing being pointed to, only the pointer. What's happening here has nothing to do with closures but everything to do with how arguments are passed into functions in js. – slebetman Apr 16 '17 at 01:39
  • *"as well as object obtaining a copy of obj"* .... No. Objects are passed by reference not copied – charlietfl Apr 16 '17 at 01:43
  • I see @slebetman that makes a lot of sense. I wasn't sure if pointers were the reason why the object value was changing. If you happen to know the ways in which variables / objects are passed into a function in js and have the time to write a comprehensive answer, I would love to read it :) – Webeng Apr 16 '17 at 01:44
  • @charlietfl "but from the results, that seems not to be the case"* :P, yeah I assumed I had been wrong there hahah, thank you for confirming it! – Webeng Apr 16 '17 at 01:45
  • @Webeng please use google for this. 'Javascript pass by reference vs pass by value' – xDreamCoding Apr 16 '17 at 01:46
  • just on a side note, if I wanted to make a copy of the object, I know I probably could do `var object = JSON.parse(obj.toString())`, but might there be a simpler way? @charlietfl @slebetman – Webeng Apr 16 '17 at 01:47
  • 1
    actually would be `JSON.parse(JSON.stringify(obj))` ... toString() produces `"[Object object]"` – charlietfl Apr 16 '17 at 01:49
  • ty for that @charlietfl I was literally seeing that error when testing it out in the developer console – Webeng Apr 16 '17 at 01:50
  • 1
    @Webeng Have in mind that using `JSON.parse(JSON.stringify(obj))` will not work if you have dates in that object. – Gerardo Furtado Apr 16 '17 at 01:50
  • 2
    @GerardoFurtado my bad...the `parse` won't return Date object...you are right. Will be jsonified date string – charlietfl Apr 16 '17 at 01:53
  • @charlietfl Yep, I was writting a comment when you just deleted yours! :-) – Gerardo Furtado Apr 16 '17 at 01:54
  • another way would be use `Object.assign()` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign – charlietfl Apr 16 '17 at 01:54

0 Answers0