JavaScript Fundamentals: Variables

I have never heard of a language that doesn’t use variables, and JavaScript is definitely not an exception to that. Variables are handled differently in each language and to become a true JavaScript expert you’ll need to understand how JavaScript handles variables too. For the most part it’s very straightforward, but there are plenty of “gotchas” you’ll want to be aware of.

Declaring a Variable

The first thing that you’ll probably want to know about JavaScript variables is that they are loosely typed. This means a couple things:

  1. You don’t need to set the type of a variable when you declare the variable.
  2. You can change the value of a variable to a different type at any time.

Instead of saying what type of variable it will be, you simply use the var keyword when you declare a variable. Like this:

1
2
3
var variableName;
// You can also set the value immediately
var variableName = 1;

In the first line where variableName was declared without a value, it will be undefined.

You can also declare multiple variables with a single var keyword simply by separating the variable names and assignments with a comma:

1
2
3
4
var var1 = 1,
var2 = 2,
var3, var4 = "4",
var5 = {};

As you can see, some variables can have assignments while others don’t, and you can also separate them out on different lines or keep them on the same line (like var3 and var4). Technically, the var keyword isn’t even necessary, though it is highly recommended because if you skip it, you could get some unexpected results. We’ll talk about that more in the section about scope.

Determining Type

Due to the fact that variables can be any type and can change type at any time, it might be necessary to check what the type of a variable is during runtime. To do this we use the typeof operator. Simply type typeof before a value (whether it’s contained in a variable or not) and it’ll spit out a string indicating what type the variable is.

1
2
3
4
5
var foo = "bar";
console.log(typeof foo); // "string"
console.log(typeof 1); // "number"
// you can also use it like a function instead of an operator
console.log(typeof(foo)); // "string"

Here are all the different results you can get from using typeof:

  • "undefined" if value is undefined
  • "boolean" if value is a Boolean
  • "string" if value is a string
  • "number" if a value is a number
  • "function" if a value is a function
  • "object" if a value is an object (but not a function. Functions are objects) or null

Other than trying to determine if an object is a certain type of object, typeof can take care of pretty much all of your type checks, though many people still make utility functions to do this for them so that they can use more semantic names (such as isString). Sometimes, the authors use entirely different means for determining types (such as jQuery’s isFunction) and sometimes they implement new type checks (such as jQuery’s isArray).

Scope

Variables in JavaScript do not have block scope like many would believe (due to its C-like syntax). Instead, variables have function scope, which means that variables declared in a function will only be available within that function (and all functions declared in that function). There is an exception, though. If you declare a variable without the var keyword, it will have global scope. This means that if you accidentally forget to add var before a variable declaration, it becomes available to everyone. Not only this, but if a variable in an scope outside that function already existed, it would now have a new value. Let’s take a look at some examples.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// currently in the global scope
var foo = 1;
function func1() {
foo = 2; // this will change the value of the global variable
bar = 3; // bar is a new global variable
var baz = 4; // baz is a new variable with scope inside func1

function func2() {
baz = 5; // baz from func1 is changed because func2 is in the same scope, so it has access to variables declared directly outside of it.
var bam = 6; // a new variable with scope inside func2
}
}

// Make sure you run func1 or nothing will change.
func1();

console.log(foo); // => 2
console.log(bar); // => 3
console.log(baz); // => Reference Error (not available in global scope)
console.log(bam); // => Reference Error (not available in global scope)

If you know what you’re doing, you can use these scoping oddities to your advantage, but if you slip up and forget a var somewhere, it could potentially break something pretty badly. If you’re in strict mode, then the line that declares bar would throw a runtime error because in strict mode if you attempt to assign a value to a variable that hasn’t been declared, it’ll fail rather than making it global.

When you’re not in strict mode, and some other developer comes and looks at that code, they won’t know if you intentionally left off var. So, for clarity and to avoid potential bugs, if you want to make a global variable from within a function, you attach it to window as a new property.

1
2
3
4
5
6
7
// currently in the global scope
var foo = 1;
function func1() {
foo = 2; // this is still ok
bar = 3; // not good. Error in strict mode
window.bar = 3; // much better. We now KNOW you wanted it global.
}

Pointers and Mutability

In JavaScript, variables are just pointers. Rather than thinking of variables “holding” values, think of them as “pointing” to a place in memory that holds a value. Also, you need to realize that all of the primitive types are immutable, meaning that they cannot change their value. However, objects (and functions because functions are objects) are mutable, meaning you can change them directly. Let’s use a code example to see how this works.

1
2
3
4
var x = 1,    // x points to 1
y = x; // y points to the same 1 in memory

x += 1; // x now points to 2

In the end x = 2 and y = 1. Since numbers are immutable, x ended up pointing to a different place in memory instead of the place in memory changing its value. Since the 1 never changed and y was never told to point anywhere different, it still points to the original 1 in memory.

1
2
3
4
var x = {},   // x points to an empty object in memory
y = x; // y points to the same object in memory

x.newProperty = 1; // x now has a new property

Since objects are mutable, x is still pointing to the same place in memory at the end, but the memory now holds additional information (a new property added to the object). Since y was also pointing to the same place in memory, it will also have this new property.

1
2
3
4
5
6
7
8
9
10
11
12
var x = {},   // x points to an empty object in memory
y = 1;

function z(obj, num) {
obj.newProperty = 1;
num = 2;
}

z(x, y);

console.log(x); // {newProperty:1}
console.log(y); // 1

This code example also demonstrates that variables are passed by reference to functions, rather than passed by value. In some languages, you can just send a value into a function, meaning the value of a variable is copied to a new space in memory so that any changes to that value won’t affect the variable outside of the function. In JavaScript, though, the reference to a place in memory is passed to the function. This means, that if the variable that was passed into the function is mutable, it can be altered from within the function. However, immutable types are unaffected by changes made in the function, such as y and num in the above example. Essentially, that code can be changed to look like the code below and run in exactly the same way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = {},   // x points to an empty object in memory
y = 1;

function z() {
var obj = x, num = y;

obj.newProperty = 1;
num = 2;
}

z();

console.log(x); // {newProperty:1}
console.log(y); // 1

So, when passing a variable in as an argument, it’s a simple assignment that’s going on, so the variables are handled the exact same way whether they’re passed in as an argument or if they are just assigned to variables within the function.

Conclusion

I hope this clears some things up for some people. I know it helped me to walk through all of these examples to be sure that I was correct. I’ll probably be referring back to this post in the future myself if I ever feel like I’m unsure about any of these points. I always seem to find something new to learn about JavaScript. God bless and happy coding.

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.