Reputation: 55
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
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
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
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
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
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
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