# JavaScript Types And Values, Explained

***This article was initially published on the Open Replay [Blog](https://blog.openreplay.com/javascript-types-and-values-explained/)***

Javascript is a dynamically typed language, which means variable types are identified at run time (done implicitly by the interpreter). As opposed to statically typed languages like Java and C++, where the developer has to explicitly define the type for each variable declared.

As a Javascript developer having a good understanding of types in Javascript, will give you a holistic view of the language and make you more confident as a Javascript developer.

## INTRODUCTION
In a programming language values that can be represented and manipulated are known as *types*. Types are just labels given to data to enable the computer to make sense of it(at low-level computers see everything as data(1s and 0s)).

It is one of the core characteristics of any programming language to have a set of *types* it supports. 
There are basically two kinds of *type* in Javascript: primitive type and object type.

In this article readers will learn the following:

* The difference between a dynamic and static type language
* The difference between a type and a value in Javascript
* The primitive types and values
* The Object type
* Different Object properties
* Object property descriptor and attributes
* Built-in Javascript Objects
* The difference between Arrays and Typed Arrays (Indexed Collections)
* How primitive and reference values are copied
* How the Javascript Stack and heap memory works with primitive and reference values

&nbsp;
&nbsp;

## TABLE OF CONTENTS
* STATIC VS DYNAMIC TYPE LANGUAGE
* TYPE VS VALUE
* THE PRIMITIVE TYPES
    * undefined
    * null
    * Booleans
    * Strings
    * Numeric types
        * Number 
        * Nan 
        * Big Int
    
    * Symbol
    
*   THE OBJECT TYPE   
    *   Object Properties
    *   Object Property Descriptor And Attributes
    *   Built-in Objects

* PRIMITIVE AND REFERENCE VALUES
    * Stack And Heap Memory 
    * Copying Primitive Values
    * Copying Reference Values

* CONCLUSION
    * Summary Of The Article 

&nbsp;
&nbsp;

## STATIC VS DYNAMIC TYPE LANGUAGE
An empty plastic container is used to store different types of items. Example— Liquid and Solid. When we decide to store only liquids in a container, that means we can't store a solid item in it right.

In a programming language, a variable is like an empty plastic container. In the sense that it is used to store different types of values.

In a statically typed language, the *type* of value that can be stored in a variable is explicitly defined by the developer. While in a dynamically typed language like Javascript *type* is implicitly set by the interpreter at run time. 

![](https://i.imgur.com/RBN5FvQ.jpg)
&nbsp;
&nbsp;

## TYPE VS VALUE IN JAVASCRIPT
According to the Javascript [Specification](https://tc39.es/ecma262/#sec-ecmascript-language-types):

> An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object. An ECMAScript language value is a value that is characterized by an ECMAScript language type.

The preceding statement means that each Javascript type has a specific kind of value(s) it accepts. For example, different types of sports have their own specific rule(s). In the same way you can't score a basket(basketball rule) in soccer, a `string` value can't be stored as a `Number` type in Javascript.

&nbsp;
&nbsp;
## THE PRIMITIVE TYPE
In Javascript, a [Primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) type is a data type with an immutable value. 


Javascript have the following primitive types([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures)):

* null
* undefined
* Booleans
* Strings
* Numeric types
    * Number 
    * BigInt

* Symbols

&nbsp;

:::info
:information_source: The primitive types appear in Javascript as literal values.
:::

```javascript=
2
4
6
8
10
true;
"good";
3.14;
null;
undefined;
```

:::info
:information_source: Or as object instances of their Constructors
:::

```javascript=
new Boolean(false); //object 
new String("happy"); // object
new Number(22); // object
```

These object instances are rarely used.
&nbsp;
### null ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null))
According to the Javascript [Specification](https://tc39.es/ecma262/#sec-null-value):

>`null` is a primitive value that represents the *intentional absence of any object value*

null is a Javascript keyword that is normally used to indicate the absence of a value. null is regarded as the only member of its type([Null type](https://tc39.es/ecma262/#sec-terms-and-definitions-null-type)), and it can be used to indicate "no value" for strings and numbers as well as objects.

When the `typeof` operator is used on null, the string "object" is returned.
:::info
:information_source: This was actually a **[mistake](https://2ality.com/2013/10/typeof-null.html)** in the early Javascript implementation. It is advisable to use the strict operator `===` instead of `typeof` when *type checking* a null value.
:::


![](https://i.imgur.com/YCRiARD.png)


This means that null can also be regarded as a special object value that indicates "no object".

For example:
```javascript=
let greetingObject = {
english: 'hello',
french: 'bonjour'
}

let greetingObject = null;  //no object

```

In the preceding code, the  `greetingObject` variable is assigned a null value after it was initially assigned to an object. The null value means that an object is expected to be assigned to a variable, but for some reason, it's not assigned. This is also the case when a `function` returns a null value.
&nbsp;

### undefined ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))
The undefined is used to indicate the absence of a value in JavaScript just like `null`. 

An undefined value is returned:
* When a variable has not been initialized.
* When you try to access an object property or array element that does not exist.
* When functions don't explicitly return a value.
* When a value is not passed to a function parameter by an argument, the value of the parameter becomes undefined.

The undefined value is the sole member of the [Undefined](https://tc39.es/ecma262/#sec-terms-and-definitions-undefined-type) type.
&nbsp;
:::info
:information_source: The  equality operator `==` considers `undefined` and `null` to be equal.

`null == undefined; // => true`

Use the strict equality operator `===` to distinguish them.

`null === undefined; // => false`

:::
&nbsp;

### Boolean ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))

According to the Javascript [Specification](https://tc39.es/ecma262/#sec-ecmascript-language-types-boolean-type):

> The Boolean type represents a logical entity having two values, called true and false.

Booleans are simply the `true` and `false` values in JavaScript.

JavaScript can also implicitly convert other types of values into booleans([truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values).


Learn more about the Boolean type [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean).
&nbsp;

### Strings ([MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
The String type is used to represent text in Javascript. However, a string value is an immutable sequence of 16-bit values, each of which represents a Unicode character.

:::info
:information_source: 16 bit value = 2^16^ (or 65,536) distinct values

:::

Important things to know about strings:

* Javascript strings(and arrays) use zero-based indexing: the first 16-bit value is at index `0`, the next index `1`, and so on.
* The *length* of a string is the number of 16-bit values it contains.
* In ES6+ strings are *iterable*, a `loop` can be used on a string.  


Learn more about Strings [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String).
&nbsp;
### Numeric Types([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#numeric_types))

Numeric types are used to represent numbers in Javascript. 

There are two Numeric Types in Javascript:

1. Number Type
2. BigInt Type
&nbsp;
#### Number Type
This is Javascript's primary numeric type. A number value can be in the form of an integer(`20`) or a floating-point number (`21.5`). [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) and [`Infinity`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity) are also considered to be number values in Javascript. The `NaN`(Not a Number) value is technically a non-numeric value a statement can evaluate to. However, the [`Infinity`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity) value represents the mathematical infinity(something larger than the natural number), they are both global constants(properties of the global object. e.g the `window` object in the browser).

![](https://i.imgur.com/qsFxYA8.png)

![](https://i.imgur.com/e2MQJMP.png)

Learn more about the Number type [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number).


#### BigInt Type

The BigInt Type was added in ECMAScript10(ES10), it is a numeric type whose values are integers. It was included in JavaScript mainly to allow the representation of 64-bit integers, which are required for compatibility with other programming languages and APIs. 

Before ES10 the maximum number value created in Javascript used either the *number literal* or the `Number()` constructor and was stored in the `Number.MAX SAFE INTEGER` which is equal to `9007199254740991`. However, with the BigInt type, we can specify numbers greater than `Number.MAX SAFE INTEGER`.  This means BigInt values can have thousands or even millions of digits.

A `BigInt` value can be created by using the `BigInt(number)` function or appending `n` to the end of an integer value.


Example:

```javascript=
const bound_number = Number.MAX SAFE INTEGER;

const unbound_number = BigInt(Number.MAX SAFE INTEGER);

const big_number = 9007199254740991n;

```
Learn more about BigInt [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt).

&nbsp;

### Symbols ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol))

The Symbol is a unique and immutable data type introduced in ECMAScript6(ES6) to serve as a non-string property name for objects. Before ES6 property names of objects in Javascript could only be strings, but with the Symbol type, we can specify property names as Symbols too.

:::info
:information_source: Symbols are not [enumerable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties), that's the reason it can't be accessed using the `Object.keys()` method on an object that uses it as a key.

:::


#### Creating Symbols:

Global `Symbol()` function.

```javascript=
let first_name = Symbol();
let person = {};

person[first_name] = "John";
console.log(person[first_name]) // "John"
```

In the preceding code a symbol `first_name` is created using the `Symbol()` function and used to assign a new property to the `person` object.


The Symbol function also accepts an optional argument that is a description of the symbol. However, the description can't be used to access the property, it is a good practice to always provide a description to make reading and debugging easier.

```javascript=
let first_name = Symbol("first name");
let person = {};

person[first_name] = "John";

console.log("first name" in person) // False
console.log(person[first_name]) // "John"
console.log(first_name) // "Symbol(first name)"

```

#### Symbols are always unique:

Every Symbol is unique, two symbols can never be equal to each other.

```javascript=
let first_symbol = Symbol("symbol_1");
let second_symbol = Symbol("symbol_1")
console.log(first_symbol === second_symbol); // False
```

In the preceding code, two identical Symbols `first_symbol` and `second_symbol` are created, even with the same descriptions they are both unique and different.

Learn more about Symbols [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol).
&nbsp;
&nbsp;

## THE OBJECT TYPE
According to the JavaScript [Specification](https://tc39.es/ecma262/#sec-object-type)

>An Object is logically a collection of properties.

An Object can be seen as a composite value, made up of multiple values(primitive values and other objects), and allows you to store and retrieve values by name. The values collected by an object are known as properties.

&nbsp;
### Object Properties
The property(property value) of an object is the core part of any object, it is made up of a name(key) and a value. Property names are usually strings(they can also be Symbols) mapped to a value.

#### Types of Object Properties

There are two types of object properties: The data property and the accessor property. 

#### Data Properties 
When an object is written like this —
```javascript=
const data_object = {
  job: 'writer',
  id: 4
}
data_object.job
// 'writer'
```
 
 In the preceding code, the `job` and `id` properties of the `data_object` object are called *Data Properties*. This is the default way of creating object properties in JavaScript(As you have seen in most Javascript code).
 
#### Accessor Properties

An accessor property is an aggregate of two functions: the `get` and the `set` function. It associates a property name(key) with each of two accessor functions(`get` and `set`) to fetch or store a value.


Example

```javascript=
const accessor_object = {
    get job() {
        return 'writer'
    }
};

accessor_object.job; // 'writer'

const data_object = {
    job: 'writer',
};

data_object.job // 'writer'
```

In the preceding code, the `job` property is created and retrieved from both the `accessor_object` and `data_object`. However, the syntax used to create the `job` property in the `accessor_object` object is different. The `get` keyword is used followed by a function declaration with the property name(i.e `job`) that returns the property value(`'writer'`). 

:::info
:information_source: The syntax for retrieving accessor properties and data properties are the same, notwithstanding how the properties are created.

`accessor_object.job; // 'writer'`

`data_object.job // 'writer'`
:::

The `get` function is called a *getter* since it is used to get the value of an object property. if the `accessor_object` is updated like this `accessor_object.job = 'developer'`, the update won't work.  This is because we need a corresponding *setter* function for the `job` property. *Setter* functions are used to set values in an accessor object.

```javascript=
const accessor_object = {
    job: 'writer',
    get name() {
        return this.name;
    },
    set job(value) {
        this.job = value;
    }
};

accessor_object.job = 'developer';
// update works because of the setter function

```

In the preceding code, the `accessor_object` now has both  `getter` and `setter` functions. The `job` property value can now be updated because of the setter function.
&nbsp;

### Object Property Descriptor And Attributes
An object property descriptor is a composite value: It aggregates multiple values known as property attributes, that define the meta-data of the value associated with a key in an object. It simply defines what the value of an object property will look like via the following property attributes. 

* [[Value]]
* [[Get]]
* [[Set]]
* [[Writable]]
* [[Enumerable]]
* [[Configurable]]

:::info
:information_source: The`[[double square brackets]]` notation is used because they are *internal properties*. Internal properties are properties used by the ECMAScript specifications(meaning they are not directly exposed like most properties). To modify internal properties we use special methods provided by Javascript.
:::

<div>
<img src = "https://mathiasbynens.be/_img/js-engines/object-model.svg">
<center> <small>Credit: <a style="color:#333; text-decoration: underline" href='https://mathiasbynens.be/notes/shapes-ics'>mathiasbynens</a></small></center>
</div>

&nbsp;

In the preceding diagram, the property descriptor of the `object` is shown containing various property attributes of  `x` and `y`(`object` properties).

Learn more about property descriptors and attributes [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties).
&nbsp;

### Built-In Objects([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects))
You should have an idea of what they are from the name' built-in' objects. Built-in Objects are simply objects that come with Javascript by default, which enables you to implement various functionalities in your application.

There are various built-in objects(check [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)) but in this article, we will look at the following:

* Fundamental Objects
* Numbers and Dates
* Text Processing
* Indexed Collection
* Keyed Collection

&nbsp;
#### Fundadmental Objects
As defined by [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)

>These are the fundamental, basic objects upon which all other objects are based. This includes general objects, booleans, functions, and symbols.

Example: When you create a "normal object".
```javascript=
object = {
    x: 3,
    y: 5
}
```
&nbsp;

#### Numbers and Dates
>These are the base objects representing numbers, dates, and mathematical calculations. - MDN

* Number
* BigInt
* Math
* Date

Let's look at the Math Object: The `Math` Object allows us to carry out mathematical operations in Javascript, through its various [methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_methods) and [properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_properties).

For example, if we want to find the square root of a number we will use `Math.sqrt(x)` method.

```javascript=
const number_value = 9;
const square_root = Math.sqrt(number_value)
console.log(square_root) // 3
```
&nbsp;
#### Text Processing
> These objects represent strings and support manipulating them. - MDN
* String
* RegExp

&nbsp;
#### Indexed Collections: Arrays and Typed Arrays
[Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) are normal objects with integer-keyed properties. It is an ordered collection of values. Each *value* is known as an *element*,  and each element has a numeric position in the array, known as its *index*. It also has a `length` property that can be used to retrieve the number of elements contained in an array.

Example:
```javascript=
const names = ['John', 'Mary'];
console.log(names.length) // 2
```

[Typed Arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) were introduced in ES6, primarily designed to work with numeric types. Typed arrays are technically not arrays(`Array.isArray()` returns `false` for them), but normal array methods can be used on them.

The difference between Typed arrays and Arrays are:
* The elements of a typed array are all numbers. Not the regular Javascript numbers(which use the 64-bit double-precision format), In typed arrays, you can specify your preferred number type(signed and unsigned integers and IEEE-754 floating-point number) and its size(8 bits to 64 bits) that you want to store in the array.
* Typed arrays have a fixed length, the length can only be specified when it's been created and can't be changed.
* The elements of typed arrays are always initialized to `0` when the array is created.

The following 11 Numeric types can be stored and manipulated in a Typed Array:


| Constructor | Numeric type |
| -------- | -------- | 
| Int8Array()  | signed bytes     | 
| Uint8Array() | unsigned bytes | 
|    Uint8ClampedArray()  | unsigned bytes without rollover     | 
| Int16Array()     | signed 16-bit short integers     |
| Uint16Array     | unsigned 16-bit short integers     | 
| Int32Array     | signed 32-bit integers     | 
| Uint32Array()     | unsigned 32-bit integers     | 
| BigInt64Array     | signed 64-bit BigInt values (ES2020)     | 
| BigUint64Array()    | unsigned 64-bit BigInt value (ES2020)     | 
| Float32Array()    | 32-bit floating-point value     | 
| Float64Array()   | 64-bit floating-point value: regular Javascript number     | 

&nbsp;
#### Keyed Collections:
> These objects represent collections which use keys. The iterable collections ([Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)) contain elements which are easily iterated in the order of insertion. -MDN
* Map
* Set
* WeakMap
* WeakSet

&nbsp;
&nbsp;

## PRIMITIVE AND REFERENCE VALUES
When a variable is assigned a value of the Javascript [Primitive Type](https://hackmd.io/1JqWCempSuy6JN3xPaGr7A?view#THE-PRIMITIVE-TYPE), the variable is said to contain a *primitive value*. However, if an Object(normal objects, arrays, and functions) is assigned as a value to a variable, the variable is said to contain the *reference value* of the Object.

The Javascript engine stores both values differently in memory—hence the stack and the heap.

### Stack And Heap Memory
The stack and heap are basically the two memory locations, where variables are stored when they are declared in JavaScript. We will use the stack and the heap to understand primitive and reference values better, especially how they are stored as static and dynamic data on the stack and heap respectively.

Due to performance reasons primitive values and reference values are stored as static data(data whose size is fixed) on the stack. In contrast, Objects are stored as dynamic data on the heap(the object reference value is stored on the stack) because of the memory flexibility of the heap.

For Example

```javascript=
let company_name = 'Netflix';
let company_age = 24;
```
In the preceding code, because the  `string` and `number` primitive values are stored in the variables `company_name` and `company_age`. The variables will be stored on the stack by Javascript.
![](https://i.imgur.com/3zgwHiM.png)

Now let's create an object that will be stored on the heap.
```javascript=
let company_name = 'Netflix';
let company_age = 24;

let company = {
    company_name: 'Netflix',
    company_age: 25
};
```
![](https://i.imgur.com/T5Zg9nk.png)

In the preceding diagram, Javascript assigns memory on the stack for three variables `company_name`, `company_age`, and `company`. A new object is also created in the heap memory that is linked to the `company` variable on the stack. Because of the link between the `company` variable and the object on the heap memory, we say that the `company` variable stores the reference value of the object on the heap memory.

### Copying  primitive values
When a primitive value is assigned from one variable to another using the `=` operator, the value is said to be *copied* to the new variable.

Example

``` javascript=
let name = 'John';
let new_name = name;
```
In the preceding code:

* A new variable `name` is declared and initialized with a value of `'John'`.
* Next, the `new_name` variable is declared and assigned the `name` variable as its value.

Under the hood, Javascript creates a copy of the primitive value `'John'` and assigns it to the `new_name` variable.
![](https://i.imgur.com/aY4B7kf.png)

### Copying reference values

When a reference value of an object is assigned from one variable to another. The variables the *reference value* is assigned to will *refer* to the same object on the heap memory. This means changes made to one variable will affect the other.

Example:

```javascript=
let company {
    company_name: 'Netflix',
    company_age: 25;
};

let tech_company = company;

tech_company.age = 30;
```
In the preceding code:

* First, a `company` variable is declared and initialized with an object with two properties `company_name` and `company_age`.
* Second, the `company` variable is assigned to the `tech_company`  variable. The two variables now *reference* the same object in memory.

![](https://i.imgur.com/ylMdQqB.png)

* Finally, the `tech_company` variable changes the `company_age` property of the object on the memory heap from `25` to `30`.

![](https://i.imgur.com/AejfPob.png)

As you know by now, the `company` and `tech_company` variables *reference* the same object, so changes made to the object via the `tech_company` variable is also reflected in the `company` variable.

&nbsp;
&nbsp;

## CONCLUSION
Now you know about the types and their various values in Javascript, you will be more aware of how you use the various types and values when using Javascript.

### Summary
In this article you learned the following:
* The difference between a dynamic and static type language
* The difference between a type and a value in Javascript
* The primitive types and values
* The Object type
* Different Object properties
* Object property descriptor and attributes
* Built-in Javascript Objects
* The difference between Arrays and Typed Arrays (Indexed Collections)
* How primitive and reference values are copied
* How the Javascript Stack and heap memory works with primitive and reference values



