2

I have the following code:

function bird(type) {
    return function (whattosay) { //return the whole function
        console.log (type + ' ' + whattosay)
    }

}

var birdRef = bird('blackbird'); 
birdRef('singing in the dead of night');

var secondRef = bird('whitebird');

birdRef('singing after that night');

I am trying to get familiar with two concepts, closure and scope chain. Well, at my first birdRef I get in return a new function object, then I invoke it after that line line. At the end I see "blackbird singing in the dead of night" in the console. I understand that in order to find the bird type var, the closure gives you a reference to the parent, and It's somewhat looks for that var in the scope chain and finally finds it, so we see the type of the bird.

Well then you have this:

var secondRef = bird('whitebird');

A new argument has been passed, so now the var "type" changed in the bird function from blackbird to whitebird.

Now I come back to my previous created function birdRef, the thing I don't understand is, what happens next:

birdRef('singing after that night');

I get "blackbird singing after that night", instead of whitebird. Well, If I am not mistaken, doesn't the birdRef function comes to it's parent function bird, and reads the type of the updated bird variable(what I mean is that he couldn't find that var in the local environment, so he looked in the outer environment and found the var "type")?

Sorry if I don't make much sense as I am new to this, and thank you for your time.

RunningFromShia
  • 590
  • 6
  • 20

1 Answers1

1

The second time you are actually calling the result of the first closure.

The following line:

birdRef('singing after that night');

Should be:

secondRef('singing after that night');

I've included a working demo below.

function bird(type) {
    return function (whattosay) { //return the whole function
        console.log (type + ' ' + whattosay)
    }

}

var birdRef = bird('blackbird'); 
birdRef('singing in the dead of night');

var secondRef = bird('whitebird');
secondRef('singing after that night');
// ^^ secondRef instead of birdRef

// Test is again.
birdRef('singing in the dead of night');
secondRef('singing after that night');

Because type was defined within the lexical scope of the function call, it is not accessible outside of that lexical scope. As is demonstrated above, unless the variable is modified within the lexical scope in which it was defined, it cannot be accessed or modified.

Random Logic
  • 132
  • 12
  • I put birdRef the second time on purpose in order to see if the bird type changed because of the previous line of code, secondRef. the idea this was to see if it affects the birdRef function, because birdRef goes up the scope chain and tries to find that "type" var, recently changed by secondRef. – RunningFromShia Oct 29 '15 at 18:43
  • 1
    No it does not go up the scope chain because type is declared within the lexical scope create by the outer function declaration that is assigned to the bird keyword. Because each time you call bird it is creating a new lexical scope which it then creates the returned function inside of. – Random Logic Oct 29 '15 at 19:01
  • I wrote [a demo](http://jsbin.com/rixusoyira/2/edit?js,console) to hopefully give you a better understanding. Basically when you add a keyword to the argument list of a function, that keyword will identify a variable that is accessible within the following scope with the value that is passed in the function call. It is the same as if you would define a variable using the var keyword within the functions scope and assign it a static value. – Random Logic Oct 29 '15 at 19:15
  • The only thing I could understand from this is that a new bird function is created in every call and somehow the computer doesn't over-write and can refer to their point in memory. I thought the scope chain = lexical environment... – RunningFromShia Oct 29 '15 at 19:49
  • It's not so much that a new bird function is created, more that every time bird is called it creates a new lexical scope in which it "builds" a new function and returns that function. The returned function reference is operating in the lexical scope in which it was declared. In more human words a function is saying "Everytime this keyword is used do this set of tasks based on the arguments provided". – Random Logic Oct 29 '15 at 19:58
  • Generally when you execute a function which doesn't have a return value, something like: function b(){ var a = 5; } b(); does the b function created as new inside the parentacies? or does the code just go backwards and perform the function (I know that every function has a code property, so maybe that's what gets invoked) – RunningFromShia Oct 29 '15 at 20:01
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93727/discussion-between-user2081462-and-random-logic). – RunningFromShia Oct 29 '15 at 20:04