whosmav
whosmav

Reputation: 55

In a function, what is happening with/without using var before the variable?

Here is my code

var a = this.innerHTML;

var b = 'blababibbaib';

if(a !== b)
    {
        c = a;
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

and with the var

var a = this.innerHTML;

var b = 'blababibbaib';

if(a !== b)
    {
       var c = a; // here with the var it makes c undefined :-(
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

The reason I was doing this is because I wanted a function for an onclick event that would change back and forth between the original and var b. Just for fun really.

But I don't understand why when you add the var in front of the c variable it makes it undefined once you click through it. Will someone illuminate me?

I'm guessing it has something to do with variable scope when used in functions????

Thanks in advance :-)

Edit:

Okay, I did this to declare it with var, but I'm still not sure why exactly.

Outside the function I added an if check for c before declaring it

if(!c) var c = '';

But like I said, I would still like to hear whats going on and why Thanks :-)

Edit 2: Thanks everybody, reading about hoisting now.

I was getting confused I think, it seems even you don't need to check for c either. Thought might matter...oh well. Thanks again

Upvotes: 1

Views: 109

Answers (6)

user1726343
user1726343

Reputation:

What is happening in the second example is equivalent to this:

var a = this.innerHTML;

var b = 'blababibbaib';

var c; // all "var" are hoisted to the top of a function body

if(a !== b)
    {
        c = a;
        return this.innerHTML = b;
    }
else
    {
        // local c variable not set yet - undefined
        return this.innerHTML = c;
    }

Obviously c is undefined here, since it is output only when it is not set. I suspect what you actually want is:

var a; //This persists after the function is invoked

myelement.onclick = function () {
    if (!a) { // Only save the value if it isn't already set
        a = this.innerHTML;
    }
    var b = 'blababibbaib';

    if (this.innerHTML == b) {
        return this.innerHTML = a;
    } else {
        return this.innerHTML = b;
    }
};

You can see it here.

As far as the first snippet is concerned, it works because the value of c is not local to the function, and persists after its invocation. When you assign or refer to a variable in a function body without declaring it using the var keyword, it automatically refers to a property of window with the same name. Consider the following:

window.c = "Hello, world.";

//Note how there is no local c variable;
//the c here refers to window.c
function test1(){
    alert(c);
}

//There is a c variable local to the 
//function, so the value alerted is not the value of window.c
function test2(){
    var c;
    alert(c);
}

test1(); // alerts "Hello, world."
test2(); // alerts "undefined"

In the first snippet, you are changing the value of window.c to this.innerHTML whenever the HTML is not "blababibbaib". When the value is "blababibbaib", you are relying on window.c to reset the element's innerHTML.

You might want to read up on hoisting in JS, as well as implicit globals.

Upvotes: 4

Mutahhir
Mutahhir

Reputation: 3832

This is a little confusing, but should be really easy to remember when you know. When you omit the var keyword while defining the variable, the variable gets attached to the global scope. This is generally an undesired in well-written programs because you have variables floating around which should've been disposed off when the scope expired.

In your case, when you add the var c = a within the if statement, even though javascript automatically hoists the variable to the function scope -- i.e. the variable name would exist -- but it won't assign it a value until it encounters the var c = a line of code. By default, any variable not assigned a value gets the undefined state.

When you've omitted the var, c is promoted to the global scope, and the global state keeps that value of c as long as you're on the page. Therefore, coming back into the else clause you'll get a valid -- but old -- value of c.

As a rule of thumb, variables defined without var aren't a good practice, and you should define all variables that you use near the start of the function to avoid any confusion with hoisting or such especially if you're from a C/C++/Java background.

Upvotes: 0

jtrick
jtrick

Reputation: 1369

When you don't allocate new memory to a variable within a particular scope, it defaults to using a variable matching that name up the parent scope chain.

Using the 'var' keyword triggers the memory allocation in the current scope, and otherwise will assign the value as a member of window, which is persistent across calls to your function.

Upvotes: 0

Sudhir Bastakoti
Sudhir Bastakoti

Reputation: 100175

That's probably, because your variable c, exist only in if statement, so you need to do:

var a = this.innerHTML;

var b = 'blababibbaib';
var c;
if(a !== b)
    {
       var c = a; // here with the var it makes c undefined :-(
        return this.innerHTML = b;
    }
else
    {
        return this.innerHTML = c;
    }

With the first code, since you have not used var c, which makes c a global variable.

Upvotes: 1

Brian Ustas
Brian Ustas

Reputation: 65519

Without the var prefix c becomes a global variable and is available in all scopes.

JavaScript only has function scope thus using var scopes your variable to the most recent function context (or global scope if not declared inside a function).

Upvotes: 1

Evan Trimboli
Evan Trimboli

Reputation: 30082

Following your logic, c will only get set in the if, never the else. So if c is a global variable that exists outside the function, it can maintain "state" between calls. If you declare it with var inside, then it becomes local to each call.

Upvotes: 0

Related Questions