Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Evaluation Questions

Tags:

javascript

var  x  =  5;
function f(y){ return (x+y)-2 }; 
function g(h){ var x = 7; return h(x) }; 
{ var x=10; z=g(f) };

I'm working through some problems from my textbook in my class to prepare for our next exam, and can't figure out how the above evaluates.

Mostly, I don't understand the call z=g(f), as when f is evaluated, it isn't provided an argument, so how does it evaluate at all? How does it know what y is?

Also, as far as scoping goes, I believe javascript treats most everything as global variables, so the last x that is set would be the x value used in function f, correct?

Thanks for any help!

Please note, these are extra problems in the back of the book I'm practicing to prepare for the exam, these are not direct homework questions.

like image 998
OogaBooga Avatar asked Nov 19 '10 18:11

OogaBooga


2 Answers

Mostly, I don't understand the call z=g(f), as when f is evaluated, it isn't provided an argument, so how does it evaluate at all? How does it know what y is?

Take it step by step.

Q: What does function g do?
A: It takes another function as a parameter and calls that function with the argument 7.

Q: So what does g(f) do?
A: It calls f with the argument 7, so it's equivalent to f(7).

Notice that writing f without parentheses does not actually call f. In JavaScript functions can be referred to and passed around as arguments just like any other variable. Functions are first class objects, and you can do a lot more with them than merely call them!

Q: What is the result of f(7)?
A: The return statement is return (x+7)-2. We need to know the value of x.

Q: What is the value of x inside f?
A: x here refers to the global variable x, whose value is 10. Importantly, the var x = 7 inside of g is a local variable, and is distinct from the global variable. The var x = 7 declaration from function g is irrelevant when we're looking at function f.

Also importantly, the statements var x = 5 and var x = 10 both refer to the same global variable. Local variables are only introduced inside of functions. Simply having naked curly braces and repeating the var keyword does not introduce a new variable in JavaScript. This is a tricky point, because in other languages like C++ this would introduce a new scope and a new variable. In JavaScript it does not. The var x = 10 could be (and should be!) written as simply x = 10.

To be honest, this is a remarkably subtle and confusing point. It makes me wonder if your textbook actually intended to test your knowledge of this idea. It is rather arcane.

Q: Okay... so the result of f(7) is what?
A: It is (10+7)-2, or 15.

like image 68
John Kugelman Avatar answered Sep 21 '22 21:09

John Kugelman


I understand why this is confusing. Let me explain what's going on here, line by line:

var  x  =  5;

You've probably got this one figured out. A new variable x is declared and assigned the value 5.

function f(y){ return (x+y)-2 }; 

This declares a function that closes around the variable x already defined. It adds this to its argument and subtracts 2, returning that value.

function g(h){ var x = 7; return h(x) }; 

This declares a function that declares a local variable x, and then calls its argument as a function and passes it the value of x, which will always be 7.

{ var x=10; z=g(f) };

This opens a new code block and declares a variable x with a value of 10. However, since this declaration is in the same scope as the earlier declaration of x (blocks do not create new scope in JavaScript!) it will actually assign the value 10 to the existing variable. Then the block calls the function g, passing in the function f as its argument. So, what will happen? Let's start with the invocation of g:

g is passed f. Remember that g takes a function as a parameter, so this is ok. g will call f with the argument 7 and return its value. So now let's consider f. f will be called with y being equal to 7, since that was an argument. x is equal to 10, since the original x var was assigned the value 10. So it will return (x+y)-2 or (10+7)-2, which is 15.

So z will have the value 15 after the script executes.

like image 35
cdhowie Avatar answered Sep 23 '22 21:09

cdhowie