3

Trying to wrap my head around Javascript scope and looking for someone to explain what's happening in the following. Hoping it'll help not just me...

var foo = {
  bar: {}
};
(function(foo, bar) {
  foo.bar = 'a';
  bar = 'b';

}(foo, foo.bar))

console.log(foo.bar) // prints 'a', not 'b', how come? 
0

2 Answers 2

6

You define two variables:

function(foo, bar)

You pass two values into them:

}(foo, foo.bar))

The value of foo is a reference to an object (that object has a property bar whose value is a reference to a different object)

The value of the variable bar is a reference to that second object.

foo.bar = 'a';

You overwrite the bar property of the first object with the string 'a'. foo.bar is no longer a reference to the second object. The value of bar is still a reference to the second object.

bar = 'b';

You overwrite the local bar variable with the string 'b'. There are now no references to the second object left. The second object will be garbage collected.

console.log(foo.bar)

You output the value of the bar property of the object that the value of foo is a reference to. This is 'a' since you modified the value of that property in the function.

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

10 Comments

Not fully correct. Try this: var foo = { bar: {} }; (function(bar) { bar = 'b'; }(foo.bar)); console.log(foo.bar);
@SimonSimCity — That just removes all instances of modifying "the first object", so when you console.log it you get the second object (because you didn't overwrite the bar property of the first object). How does that conflict with my answer?
@Scimonster, For me it returns {} - not the (by me) awaited 'b'.
@SimonSimCity I expected the {}, because again, it's overwriting the local variable, not the reference to foo.bar.
@SimonSimCity – The local bar variable is never a reference to foo.bar. You can't have a reference to a property. foo.bar and bar are both references to the same object. They can be overwritten independently. There is no connection between foo.bar and bar other than that they are sometimes given the same value.
|
4

foo is an object, which is passed by reference. bar is passed by value. When bar is overwritten, it loses the relation to foo.bar. Hence, foo.bar is "a"`, which is what it was set to in the function.

var foo = {
  bar: {}
};
(function(foo, bar) {
    // foo is {bar:{}}
    // bar is {}
  foo.bar = 'a';
    // now foo is {bar:'a'}
  bar = 'b';
    // now bar is 'b'
    // bar has no relation to foo.bar anymore

}(foo, foo.bar))

console.log(foo.bar) // prints 'a', not 'b', how come? 

3 Comments

I think OP is asking that foo inside the function is not equal to the foo outside of function scope.. it should print {} but not a. I might be wrong though..
foo refers to the same object in both scopes.
foo.bar (the argument to the function) is an object as well. Neither the foo nor the bar parameters are passed by reference

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.