Vars And Values

Sometimes I hear JavaScript dev throw around the terms vars and values as synonyms for each other. Realising that they’re not was a serious ‘aha’ moment for me - and making the distinction about it can make talking and thinking about code clearer by far.

values

JavaScript values split neatly into two camps - objects and primitives.

Primitives

Primitives are familiar to us all - in the form of strings, numbers, booleans, null and undefined. They’re immutable - meaning you cannot alter a value. If you want to alter one, you have to create a new one by performing some operation on the original.

Primtives implement value equality - two primitives are considered equal, even if they were created separately, if they represent the same logical value: 1 === 1.

Objects

Objects are mutable by default, and are most commonly found in the form created by {} or [] - often referred to as objects and arrays (since the forms are sugar for new Object and new Array respectively). Objects are mutable - meaning that you can alter the very value itself.

Objects implement (what I will term for the sake of convenience) equality by identity. An object gets a unique identifier on creation, and is only considered to be equal to another object when that unique identifier matches. Therefore, { x: 3 } !== { x: 3 }.

vars

A variable is simply a name for a value within a scope, that can be changed. They can be created by the variable statement, by a function declaration, or via a parameter. You could think of it as a box that holds an address to a value - it’s a conceptual model that I haven’t managed to break when thinking about JS.

// creating variable `a` via the var statement, and assigning the value `1` to it
var a = 1

// creating variable `b` via a function declaration,
// and the variable `c` as the parameter to that function
function b(c){
	var d = 'my value'
}

Just a couple of examples

So how does this affect common, every-day situations that you want to talk to others about?

for loops

The primary mechanic of a for loop is by replacing the value held by a var; not from altering the value:

for ( var i = 0; i < 5; i = i + 1 ) console.log(i)

In the above example, variable i holds the value 0 intially. In each subsequent loop (while the i still holds a value less than 5), the variable is updated to hold a new value, created by operating on the old value.

passing arguments to functions

When you place a variable in the comma-seperated, parens-encapulated part of a function call, you’re really simply taking the values variables hold, and passing those to a function.

var add = function(a, b){ return a + b }

var num1 = 1
var num2 = 2

add(num1, num2) //= 3

In this case, num1 and num2 get substituted with 1 and 2 respectively. Within the body of the function, 1 gets assigned as the value held by variable a, and 2 gets assigned as the value held by b.

You can prove this is the case by changing the variable within the function, and then inspecting the variable that referred to the same value outside the function:

var inc = function(a){ a = a + 1; return a }

var num = 1

inc(num) 	//= 2
num 		//= 1

The value assigned to a function’s parameter is identical to the value passed in. We’ve already seen that that means that a variable gets the same value as far as primitives are concerned - but the same is true of objects. This means that any change done by a function on that object will be seen when any other variable that refers to that object is inspected.

// takes an object, and adds the .isMutated property
var mutate = function(o){ o.isMutated = true; return o }

var myObject = { x: 3 }

mutate(myObject) //= { x: 3, isMutated: true}
myObject         //= { x: 3, isMutated: true}

This might trick you into thinking that the operation within mutate actually changed which value myObject holds - but the primitive example shows this is not the case; altering one variable does not affect another variable. it’s the value itself that gets mutated.

At the end of the day…

It’s possible that every dev knows this - and those that use the terms interchangably do so out of laziness. I’m often convinced this is the case when I talk to people I know are fairly up-to-speed on other aspects of programming.

Still, I think there’s a lot of value in separating the two concepts, because it leads to a far clearer understanding of what you have to worry about changing where.

Deeper discussions need more crystal clearly defined terms - heaven knows we have the odds stacked against us by our choice of subject matter from time to time in any case.