Are variables statically or dynamically "scoped" in javascript?
Asked Answered
S

7

32

Or more specific to what I need:

If I call a function from within another function, is it going to pull the variable from within the calling function, or from the level above? Ex:

myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

What does myVar end up being if callMe() is called through runMe()?

Semester answered 6/6, 2009 at 4:16 Comment(3)
Why don't you run it and find out?Vitric
Isn't it better to document the question so others can see it as well?Ionize
The answer is actually a good way to start to understand lexical vs dynamic scope IMHO, so this is good to post hear, but Sasha isn't wrong to remind beginners that running and experimenting is always a good policy.Gaylor
P
52

Jeff is right. Note that this is not actually a good test of static scoping (which JS does have). A better one would be:

myVar=0;

function runMe(){
    var myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

runMe();
alert(addMe);
alert(myVar);

In a statically scoped language (like JS), that alerts 10, and 0. The var myVar (local variable) in runMe shadows the global myVar in that function. However, it has no effect in callMe, so callMe uses the global myVar which is still at 0.

In a dynamically scoped language (unlike JS), callMe would inherit scope from runMe, so addMe would become 20. Note that myVar would still be 0 at the alert, because the alert does not inherit scope from either function.

Phthalocyanine answered 6/6, 2009 at 5:11 Comment(2)
the exception is the 'this' keyword which behaves like a dynamically scoped variableCortisone
@Cortisone 1. By passing 'this', one is fixing the execution context of the function/method. This exhibits a behaviour of a dynamic scoped language, but not same. 2. Also closures are not be confused with dynamic scoping.Quiescent
M
5

if your next line is callMe();, then addMe will be 10, and myVar will be 0.

if your next line is runMe();, then addMe will be 20, and myVar will be 10.

Forgive me for asking - what does this have to do with static/dynamic binding? Isn't myVar simply a global variable, and won't the procedural code (unwrap everything onto the call stack) determine the values?

Mannered answered 6/6, 2009 at 4:21 Comment(0)
B
3

Variables are statically scoped in JavaScript (dynamic scoping is really a pretty messy business: you can read more about it on Wikipedia).

In your case though, you're using a global variable, so all functions will access that same variable. Matthew Flaschen's reply shows how you can change it so the second myVar is actually a different variable.

This Page explains how to declare global vs. local variables in JavaScript, in case you're not too familiar with it. It's different from the way most scripting languages do it. (In summary: the "var" keyword makes a variable local if declared inside a function, otherwise the variable is global.)

Bissau answered 6/6, 2009 at 5:38 Comment(0)
P
1

Unless you use the keyword var to define your variables, everything ends up being a property on the window object. So your code would be equivalent to the following:

window.myVar=0;

function runMe(){
    window.myVar = 10;
    window.callMe();
}

function callMe(){
   window.addMe = window.myVar+10;
}

If you keep this in mind, it should always be clear what is happening.

Phenice answered 20/6, 2011 at 12:54 Comment(0)
F
1

I would like to add that lambda expressions are also statically scoped at the location that the expression is defined. For example,

var myVar = 0;

function foo() {
    var myVar = 10;
    return { bar: function() { addMe = myVar + 10; }}
}

var myObj = foo();

var addMe = 6;
alert(addMe);

myVar = 42;
myObj.bar();

alert(addMe);

This will display 6 and 20.

Forman answered 8/1, 2015 at 19:9 Comment(0)
C
0

As far as I understand, any variable without the var keyword is treated global, with it, its local scoped, so:

// This is a local scoped variable.
var local_var = "something"; 

// This is a global scoped variable.
global_var = "something_else";

As a good JS practice, it is recommended to ALWAYS add the var keyword.

Cowrie answered 6/6, 2009 at 6:7 Comment(0)
O
0
myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

As far as the output is concerned myVar and addMe both will be global variable in this case , as in javascript if you don't declare a variable with var then it implicitly declares it as global hence when you call runMe() then myVar will have the value 10 and addMe will have 20 .

Oder answered 1/7, 2017 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.