Values and variables: learn the rules of javascript!

Do you know what Harry Potter, Star Wars, the Marvel Universe and Game of Thrones all have in common? Rules and boundaries.

Yes, we can create vast imaginary, fictional realms for our minds to be entertained by - and in my earlier blog post I talked about the great storytellers of our time creating entire fantasy worlds as the setting for their tales. But that doesn’t mean those worlds don’t have strict guidelines!

The story of javascript is no different. It can do some weird and wacky things. But there are still rules people! 

You can either go on Twitter and join the multitudes complaining about how tricky and nonsensical javascript is compared to other programming languages. OR, you can learn the rules.

One Rule to Rule Them All

Earlier we visualised a Javascript program, and imagined primitive values as islands. The main takeaway:  they can be found with a set of coordinates  🗺️📍- a reference to a particular spot in the program's memory.

That’s all good and well, but it doesn’t explain how we are able to use these coordinates in our program.

If there is one rule I want you to remember above all others, it’s that we use expressions to locate values.

And by expression I mean a crazy genie with a big smiling expression on his face.

Genies are the workers in the Javascript universe. There are lots of them, and we use them EVERYWHERE in our code, whether it’s writing a string value, executing a function or accessing an object property.

The definition of an expression is code that results in a value. This is the same as asking, ‘Where can I find this value? 🙋

Every time you write an array or object literal { }, the name of a variable, a function call or you access an object property, you are using an expression.

5 // is an expression.  By literally writing 5 down ( why we call them literals, right? ) 
  //you are asking the genie, 'Where is the number 5 in this javascript engine?'

'str1' === 'str2' // Where are these two strings, and are we talking about the same string - ie are they the same Locate the true or false island depending on the outcome 

myObj.title //Where is this object and does it have this property ❓ 
            //Locate the true or false island depending on the outcome 

count() // Where is the function count value so I can execute it?

Only genies can answer these questions. Using the value island’s coordinates, they find the value you’re looking for and POINT at it.

Whenever you write code which references values, or results in a value, you are asking a genie to find the value for you  🧞‍♂️. 

Genies as variables

The problem is, everytime you want to find a value you have to ask a new genie, and explain to him what it is you’re looking for. Very inefficient. Wouldn’t it be easier to ask for the same genie each time?

What we can do instead is kindly ask a genie to point at a particular value, and we give that genie a name we choose - like count.

let count = 0;

Now, all we need to do is ask for count when we’re looking for the value 0; 

There is a special term for this process: ASSIGNMENT.

When this happens, the genie flies down to the chosen island. You may have noticed in the some of the images of the islands (once you do, it’s almost impossible to forget 🤣), value islands all come with a toilet and microphone. I could say it’s because value stands for Voice Activated Loo, like valooooo. But the REAL reason is do with assignment.

When we name a genie, he flies down to the island. And he sits on the loo seat. ‘This is now MY island’ he thinks, while trying to forget his throne is a toilet.

How does this help us remember the term, ‘Assignment’? The first 3 letters should imprint it in your memory forever.

Take a look at all these named genies - the kind of genie variables we would keep in an app:

var data = {};
const errorMessage = 'The form is broken. Darn!';
let count = 0;
let x = 10;
const endpoint = '/myApi';

Now you might be thinking of the different ways to name a genie, or in javascript terms, declare a variable, like let , const and var. This is to do with scope, and for the moment it is out of scope of this post (see what I did there?). This is something we will address later.

Genies in ships

We now know how we can find individual value islands. But what about a collection of values? For that, we use objects - and objects are flying ships!

These structures do not keep values in them. They keep pointers! These pointers might have a name (keys, in objects) or a number (index, in arrays). 

The pointers can be imagined as the crew members in the flying ships. If you take a closer look, you will see they are genies! They are each responsible for finding a specific value.

How do we, as the programmer, access a property of an object? We don’t ask the genie crew member directly. That would be breaking the rules!

Instead we ask the ship captain. This well dressed fellow doesn’t represent anything visible in our code. Instead, he is a representation of the internal process of accessing an object property.

There are 2 ways the captain will carry out our instructions, when we're looking for a specific object property.

Dot notation

In code this looks like:

const developer  = {
  name: 'Sarah'
}
developer.name // 'Sarah'

In The Great Sync, this represents the captain leaning over the railing and pointing his gun down at a genie crew member.  From the genie's perspective, it would be like looking into the barrel of a gun (a giant dot).

Square bracket notation

In code this looks like:

developer['name'];

Notice the speech marks in ['name']. This is because the captain is shouting the name of the genie through the deck hatch [ ], to the crew members below.

When either dot or square bracket notation is used, we are asking for a genie to shine his light down on the value we want - and it’s the captain’s job to instruct the appropriate crew member to find it for us!

A ship shines its light down on an island.

Objects vs Arrays

An array is also an object - a kind of ship for storing properties. But this ship is clearly different. It is long in ship, and the properties are lined up in order. The crewmembers in object ships sit in windows in a haphazard manner. There is no order to where they sit, and the genies pick and choose their windows randomly. The only way the captain is able to locate the property is by using the genie's name.

The captain on an array submarine ship prefers a different strategy. He orders his crewmembers into a specific order, and instead of using a name for the genie ( submarine captains have a terrible memory ), he simply shouts a number.

The first number is always 0. This is called zero-indexing, and its the system preferred for giving a genie a number.

We can remember this by picturing the first window as circular.

A submarine ship, representing an array.

Now, due to the constraints of the submarine ship, it is very difficult for the captain to lean over the railing and shout the genie's number. After all submarines were designed for being underwater, right? It is much easier for the captain to go inside to shout the property's number when he needs him.

For that reason, arrays ALWAYS use square bracket notation for accessing property values.

const ar = [34354, 54545, 343433];
ar[0] // 34354

Property access is an expression

As you now know, expressions in our mental model are genies finding value islands for us. That's what happens when you use a variable. But it's also what happens when we access a property in an object or array.

This is SUPER important.

If we every square or dot notation is an expression, resulting in a value, it means we can CHAIN these expressions if that value is another object or array.

Take a look at this code:

const ar = [ [ 'A', 'B', 'C']];

ar[0][0];

This results in the string value 'A';

The first ar[0] is an expression. This results in the genie property with number 0, finding us this array submarine value: [ 'A', 'B', 'C']

So the expression: ar[0][0] would be the same as:

const ar = [ [ 'A', 'B', 'C']];

const insideArray = ar[0];
const firstLetter = insideArray[0];

Do you see how powerful this is?

Thinking in terms of expressions is a fundamental way of thinking about your javascript code. Always ask yourself, is this an expression? And if so, what value does it result in?

Because of the way expressions work, we can create some complicated chained expressions for accessing values deep inside an array or object. For example, look at this expression for executing an object method:

const utility = {
    methods: [
        {
            description: 'console log a random string',
            consoleRandomString: function(ar){
                console.log('This is a random string;')
            }
        }
    ]
}

utility.methods[0].consoleRandomString();

utility.methods results in an array. We then access the first value of this array, which is another object. We then access the consoleRandomString genie property, which points at a function. Since we are able to find the function, we can execute it with ( ) at the end of the expression.

This is the longer way of writing it out:

const utility = {
    methods: [
        {
            description: 'console log a random string',
            consoleRandomString: function(ar){
                console.log('This is a random string;')
            }
        }
    ]
}

const methods =  utility.methods;
const firstMethod = methods[0];
const consoleRandomStringMethod = firstMethod.consoleRandomString;

consoleRandomStringMethod();

** Always remember, the captain shouting for a genie means a value island MUST be found. That value could be a primitive value like a string, but it might also be another object or array or a function, which you can then chain onto.

Missing crew member 😱

It’s the captain’s worst nightmare. There’s a missing genie crew member on board the object ship. He only realises this when we, as the programmer, ask for a genie who is not there. Take this example:

const blog = {
  title: 'Learning Object Properties'
}

blog.content;  // ??

What happens? Does the captain panic? Does he crash the ship, terminating the entire program?

Of course not. He has a job to do - find us a value. If there’s no crew member ready to get us the value we need, he calmly instructs the closest genie to point his spotlight down at the undefined island.

Why undefined? It’s just so easy to find! This volcanic, molten island is always present and easy to locate with its large plume of smoke.

This way, the captain does his job and our program keeps running. We receive a value back - even if its not the one we intended.

The gaping hole in our mental model

Objects, arrays and functions are not primitive values. They are not natural islands, with a set of coordinates. They live in The Heap Multiverse, which is an invisible parallel realm. If this is so, how can genies find them?

const myObj  = {};  

How is the above line even possible, if there is no island with a loo for the genie to be assigned to?

We need another layer in our mental model. But no, genies won’t suddenly get special goggles to see into the Heap. That would be like Harry Potter sending his owl Hedwig to fetch the horcruxes, or Frodo traveling to Mordor by car. It’s not that easy.

Stick to the rules, people! 😜

Looking forward to addressing this topic in the next post. But before you go, why not practise some dot and square bracket notation by answering this question:

Practice Question 1

Write the expression for accessing the id property of the user's first course.

const data = {
    user: {
        username: 'dakr',
        courses: [ 
            { 
                id: 2, 
                chapterProgress: {}
            },
            {
                id: 1, 
                name: 'Learn Js', 
                chapterProgress: { 
                    1: { 
                        progress: 100,
                        tags: ['javascript', 'fundamentals'] 
                    }, 
                    2:  { 
                        progress: 50 
                    }
                } 
            }, 
        ]
    },
}

Practice Question 2

Write the expression for accessing the 2nd tag string value of the first chapter of the second course of the user.

TIP** I recommend drawing this. Draw

const data = {
    user: {
        username: 'dakr',
        courses: [ 
            { 
                id: 2, 
                chapterProgress: {}
            },
            {
                id: 1, 
                name: 'Learn Js', 
                chapterProgress: { 
                    1: { 
                        progress: 100,
                        tags: ['javascript', 'fundamentals'] 
                    }, 
                    2:  { 
                        progress: 50 
                    }
                } 
            }, 
        ]
    },
}

© 2023 Code Imagined - The Great Sync. All Rights ReservedView the Terms & ConditionsView the Privacy Policy
kylo@thegreatsync.com