DevTech

Discussing the Latest Development Technologies

JavaScript, jQuery, TypeScript: Chapter 3, part 1

Setting the Foundation: JavaScript Data Types


Because of the way the mind works, it is easiest to learn when we focus on one thing at a time.  However, when taking on a subject as large as JavaScript which has been in use since it was originally created by Brendan Eich for use in Netscape Navigator 2.0 back in September of 1995, it can be a challenge to know what to focus on first.  Additionally, if you don't get your basic foundations set in place it can be much more difficult to learn advanced concepts later.

That's why I want to take you back to a very basic concept which underlies everything that goes on in JavaScript: The Type System.

At first glance, you may think focusing on the type system is too simple and boring, but I promise I'll keep it short and lively and when we're done you'll understand how JavaScript works better than ever.

How JavaScript Handles Types


In JavaScript – as in many high-level languages – all types can be organized into two categories:

  1. Primitive types -- memory address indicates where the data (or value) is stored.*
  2. Reference types -- memory address indicates where the object is stored.*


* This statement may be confusing. I'll explain this in just a few moments.


First, let's take a look at the primitives.
There are only six primitive types in JavaScript and they are:

  1. Number
  2. Boolean
  3. String
  4. undefined
  5. Null
  6. Symbol (New to JavaScript 2015)

Those last three probably look a little odd to you and we'll get to them, but first let's take a look at the first three and learn why it is important to understand that all of these are primitive types.  Then, we'll delve into Reference Types and how they are different. The knowledge of the contrast of these two types will actually help you understand how the JavaScript Interpreter – which runs all of your JavaScript code – works and how that creating Objects (Reference types) is so much different than creating these Primitive types.


Creating any one of the Primitive types is very easy in JavaScript.
Just type the keyword var followed by the name you want to use to refer to your variable and then set it to some value.

var counter = 0; // becomes a Number type
var isConfigured  = false; // becomes a Boolean type
var firstName = “David”; // becomes a String

typeof Operator Indicates Type From JavaScript Interpreter

We can use the typeof operator to determine what type the JavaScript Interpreter believes a variable is.  Of course, whatever the JavaScript Interpreter believes your variable type to be is what it is.

Here's some code to show you how the typeof operator works.

var counter = 0; // becomes a Number type
var isConfigured  = false; // becomes a Boolean type
var firstName = “David”; // becomes a String
console.log("counter is a " + typeof counter);
console.log("isConfigured is a " + typeof isConfigured);
console.log("firstName is a " +  typeof firstName);

After you run this code and view the console output you should see the following:

counter is a number
isConfigured is a boolean
firstName is a string

See It Run At JSFiddle

JSFiddle is a site that allows you to create HTML, CSS and JavaScript and run it in your browser.

I’ve taken the previous code and added it to a script there so you can see it run if you like.  To check it out, just point your browser at: https://jsfiddle.net/raddevus/x7zw0cka/

NOTE: The script includes some code (document.getElementById(“1”)) that gets the HTML DIV with a specific ID and set its text to the output.  I won’t explain that code right now but we’ll learn all about it later.

A Closer Look At Your Number Variable

Now allow me to go back to that somewhat odd statement I made about primitives where I stated:

"...memory address indicates where the data (or value) is stored."

 

What does that mean?
To understand it better you have to remember that all data is stored in memory at some addressable location.  Data has to be stored that way so that other program elements can access it. Otherwise, if there was no way to tell where the data was stored, there would be no way the computer program could manipulate or display the data and that data would become inaccessible and useless.

You Write JavaScript, You Control Memory Chips

Also, keep in mind that down at the bottom, somewhere the value you indicated you want to store is actually stored in memory somewhere which has a unique address.  That's right, you are actually controlling the switches on a memory chip somewhere in the computer simply by typing:

var x = 55;
 

Again, all you have to do to create a Number in JavaScript is write code like the following:

var x = 31;
var z = 56;

What The JavaScript Interpreter Does

The JavaScript Interpreter notices that you've set the value to a numeric and decides that the type will be Number.  Since it is a Number, the Interpreter knows that it will require a certain number of bytes to store up to a maximum value.
It is necessary for the Interpreter to know what type it is because of what is really going on behind the scenes – at the lower level of computing.  When you simply create a Number variable (var counter = 5;) the Javascript Interpreter has to do a some things so the computer's processor knows what you want to do.


Here are some of those things the Interpreter does:

  1. Determine the data type so it knows how many bytes of memory it needs to store the data
  2. Find a memory location which has enough contiguous slots to store a Number type.
  3. Create an entry in an internal lookup table to store the name of your variable with the name of your variable – so it can know where your variable is stored in memory when you refer to it using the name you defined.


First Step: Determine Type

The Interpreter needs to know the data type because each type requires a different amount of memory.

Second Step: Find Memory

To complete the second step, the JavaScript Interpreter has to know the number of bytes that a Number type takes up in memory.

The Architects of the JavaScript Interpreter

In the case of a primitive type (Number, Boolean, String, etc) the architects who created the JavaScript Interpreter have decided that each of them will take a predetermined number of bytes in memory.

JavaScript Primitive Number: 64 bits (8 bytes)

Currently in JavaScript running in browsers Number types get 8 bytes (64 bits) of memory space.  Some architect made that decision as a trade-off on the max value that you can store and the memory it will take up for every Number in your program.

Keep in mind that since they’ve chosen 8 bytes for a Number then the max number you can store in the Number type is : 1.7976931348623157e+308

That is a huge number and you can check that number by typing the following in your browser’s developer console and press <ENTER>.

Number.MAX_VALUE

Now, let’s continue our discussion of what happens in memory.


At the lower level where the CPU (main processor) is running and where memory is read in bits, it makes things much easier for a low-level programmer when data is written in sequential memory addresses and that’s basically why data is stored in contiguous memory locations (memory addresses that are next to each other).

What It Looks Like

When you create a new number variable the JavaScript Interpreter goes out and finds 8 sequential bytes in the addressable memory space that is available to it and sets the bits it finds there to represent the value you have stored.

var counter = 27;  

Interpreter stores 27 at the address 0x00FFC0.
counter in memory



Take a close look at Figure 1.
Imagine that each rectangle represents a byte of memory.  Most modern computers only allow you to address one byte of memory (not down to bit level) and so each address represents that one byte.  In our case when we wrote var counter = 27; the Interpreter found 8 bytes of memory which starts at address 0x00CCF0 and it sets the bits to equal 27.

Also, note that even though we can store the value using only the first byte, the Interpreter (and web browser and Operating System) actually set aside the entire 8 byte block of memory.  I've set those bytes to have all their bits zeroed out to indicate that they are in use. That means nothing else can use those bytes or else JavaScript would interpret that to mean that the value of counter had changed.  That memory (that set of eight bytes) is solely under the control of JavaScript for the purpose of storing values to the counter variable.


Reading and Writing That Memory


The JavaScript Interpreter remembers that your name of counter is how it will get to that memory.  That way when code further down in your program does something like:

counter++; // increment the counter

Then it can retrieve the value that is stored there (27), add one to that value and store it in the same place again so that memory will now look like what you see in Figure 2: Value 28 stored at location.

counter is incremented

Memory Addresses Are Arbitrary

Please keep in mind as you study these figures which represent memory that the addresses are completely arbitrary and made up for instructional purposes.  It’s just a way to explain to you what is going on in memory and the memory addresses would change each time the code is run.

Previously the value was :     00011011  (decimal 27)

Now the value is :                00011100 (decimal 28)


Value Stored At Address Is Changed

The point here is that the value stored at the memory address has changed.  Also, now that the Interpreter has stored the address where this data is located, you cannot change that address within this program.  It is locked. That means you can update the value at the address by changing the value of your variable, but you can never change the address that the variable points to -- the location where the data is stored.  Interestingly, as a matter of fact, in other languages (C, C++) there are pointer variables which allow you to change the address the variable points to.


In just a moment we will contrast this to what happens when a Reference type is changed and you will discover it is very important to your understanding of how JavaScript works.

undefined Will Make More Sense Now

Now that I've explained that, I can better explain to you the undefined primitive value.  Remember when I told you that when you set the variable to a value then the JavaScript Interpreter decides what type it is?  

 
 

Well, suppose you do the following in JavaScript:

var x;

What type is x?  The JavaScript interpreter bases the type on the data that is stored in the variable, but we have not stored any data in the variable yet so it’s type is undefined.

It is an undefined and we can prove it with the following code:

var x;
console.log("x is " + typeof x + " type");



Now, let's think about what JavaScript has to do in this case.  It cannot determine the type and yet it has to keep track of the fact that you are attempting to refer to a new variable named x.  But, what should the value of x be? In many languages (C++, C#, Java – no relation to JavaScript) it has a special value referred to as null.  But in JavaScript the architects have created another special value called undefined for this case.

In this case, the variable has not had any memory assigned to it. It cannot, because the Interpreter has no idea how much memory the thing will take up in memory, since it does not yet know the type.


My Guess At How undefined Is Defined

Here's my guess at what JavaScript does.
Somewhere way down in memory, there is one lonely address that has an undefined type sitting in it.  It may look something like what you see in Figure 3: the one undefined object in the address space.

undefined in memory

Then, when you create a new variable without setting it's value, the Interpreter stores the name of your variable in its lookup table and then sets its value of its address to that location (0x000001) so that when you ask what type var x is, it returns the type it is pointing to: undefined.

That is supposed to indicate to the JavaScript developer that the variable has not had its value (or associated type) set yet.

So far we've looked at two of the primitive types Number and undefined.  Let's take a closer look at the Boolean and String types, because they are very similar to Number, then we'll look at our Reference types and it'll be a bit easier to understand the null type.

Booleans Are Easy, But Remember true/false Are Lowercase

A Boolean simply allows you to create a variable that stores only two states: true or false.

You can create a Boolean variable very easily:

var isConfigured = true;
console.log("isConfigured is a " + typeof isConfigured);


If you run that code in your console window you will see the result shown in

Figure 4, below.

 

 

Notice that the true is lowercase.  It has to be because lowercase true and lowercase false are keywords in JavaScript and JavaScript is case-sensitive so True and False are not keywords.

You can see that by running this code:

var isConfigured = False;
console.log("isConfigured is a " + typeof isConfigured);

False is undefined in JavaScript so you get an error as soon as you attempt to set the variable.

False is undefined

Boolean, Probably Stores In One Byte

A Boolean probably stores in one byte since you could literally store it in one bit (either 1 or 0).   The Boolean probably looks similar to what is shown in Figure 6: Boolean value of true (1) stored in memory.

isConfigured boolean stored in memory

If the value is false, then most likely all bits are 0 with a final value of 0.  However, notice again, that it stores the value of the variable at the memory address because it is a primitive type (not a reference type).

Summary of Chapter 3, Part 1

We covered a lot of material in this part and we took a different view of the primitives in memory in an effort to describe how data types are stored from a computer science perspective.  I believe that understanding this will open you up to better understanding what JavaScript and your browser are doing behind the scenes as you write code.

Loading