# Explaining Value vs. Reference in JavaScript

## **JavaScript variables**

In JavaScript, a variable is a named reference to a memory location that can hold different types of data, such as numbers, strings, booleans, objects, or functions. To access a variable or modify the data stored in a variable, we use its name.

If you have a basic understanding of computer memory then you must know that Computer memory has millions of cells on it and every cell has its own address

![https://cdn.hashnode.com/res/hashnode/image/upload/v1684952050726/05637dcb-66e9-4c08-a66a-eeef3ff5a894.jpeg?auto=compress,format&format=webp](https://cdn.hashnode.com/res/hashnode/image/upload/v1684952050726/05637dcb-66e9-4c08-a66a-eeef3ff5a894.jpeg?auto=compress,format&format=webp align="left")

The problem is we can't use this address directly in our program. because you know the computer works in the binary system and in the binary system this memory address looks too weird and confusing. also, it's almost impossible to memorize.

Here variable comes in to solve this problem.

Variable gives us the simplest solution to handle it. We can simply create a variable and assign it to the value we want to store. now we don't need to memorize the weird and confusing memory address we can do the same using a simple and human-readable name.

![javascript Variables Beginner Thinking (robiul.dev).jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1684952122668/b98658d6-7609-4b67-b215-dc350fdf01b9.jpeg?auto=compress,format&format=webp align="left")

That means,

* Creating a variable
    
* Giving a standard name to the variable
    
* Assigning a value to it.
    

Think of these steps as

* Taking a container
    
* Labeling it
    
* Putting something in this container.
    

![javascript Variables Beginner Thinking (robiul.dev).jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1684952241518/883c0dc6-3453-4b62-bf5f-f5071bb66d59.jpeg?auto=compress,format&format=webp align="left")

---

**Javascript** has 5 data types that are passed by ***value***: `Boolean`, `null`, `undefined`, `String`, and `Number`. We’ll call these **primitive types**.

**Javascript** has 3 data types that are passed by ***reference***: `Array`, `Function`, and `Object`. These are all technically Objects, so we’ll refer to them collectively as **Objects**.

# <mark>Primitives</mark>

<mark>If a primitive type is assigned to a variable, we can think of that variable as </mark> *<mark>containing</mark>* <mark> the primitive value.</mark>

```javascript
var x = 10;
var y = 'abc';
var z = null;
```

`x` *contains* `10`. `y` *contains* `'abc'`. To cement this idea, we’ll maintain an image of what these variables and their respective values look like in memory.

![](https://miro.medium.com/v2/resize:fit:875/1*PdKLlT7zUrmDBZUOBsZh7w.png align="left")

![](https://miro.medium.com/v2/resize:fit:875/1*PdKLlT7zUrmDBZUOBsZh7w.png align="left")

When we assign these variables to other variables using `=`, we **copy** the value to the new variable. They are copied by value.

```javascript
var x = 10;
var y = 'abc';var a = x;
var b = y;console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
```

Both `a` and `x` now contain `10`. Both `b` and `y` now contain `'abc'`. They’re separate, as the values themselves were copied.

![](https://miro.medium.com/v2/resize:fit:875/1*MZ3AcwELYZ2ONYFg3LiTXQ.png align="left")

Changing one does not change the other. Think of the variables as having no relationship to each other.

```javascript
var x = 10;
var y = 'abc';var a = x;
var b = y;a = 5;
b = 'def';console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
```

## [Primitive Types](https://gist.github.com/branneman/7fb06d8a74d7e6d4cbcf75c50fec599c#primitive-types)

The in-memory value of a primitive type is its actual value (e.g. boolean `true`, number `42`). A primitive type can be stored in the fixed amount of memory available.

* null
    
* undefined
    
* Boolean
    
* Number
    
* String
    

Primitive types are also known as scalar types or simple types.

---

# Objects

This will feel confusing, but bear with me and read through it. Once you get through it, it’ll seem easy.

<mark>Variables that are assigned a non-primitive value are given a </mark> *<mark>reference</mark>* <mark> to that value. That reference points to the object’s location in memory. The variables don’t actually contain the value.</mark>

Objects are created at some location in your computer’s memory. When we write `arr = []`, we’ve created an array in memory. <mark> What the variable </mark> `arr` <mark> receives is the address, the location, of that array.</mark>

<mark>When we assign and use a reference-type variable, what we write and see is:</mark>

```javascript
1) var arr = [];
2) arr.push(1);
```

<mark>A representation of lines 1 and 2 above in memory is:</mark>

1.

![](https://miro.medium.com/v2/resize:fit:875/1*h1aXuPwCyhu6GKwgeFMLDw.png align="left")

2.

![](https://miro.medium.com/v2/resize:fit:875/1*HaemMnuU05EW1b3BZPubIg.png align="left")

Notice that the value, the address, contained by the variable `arr` is static. The array in memory is what changes. When we use `arr` to do something, such as pushing a value, <mark>the Javascript engine goes to the location of </mark> `arr` <mark> in memory and works with the information stored there.</mark>

## [Reference Types](https://gist.github.com/branneman/7fb06d8a74d7e6d4cbcf75c50fec599c#reference-types)

A reference type can contain other values. Since the contents of a reference type can not fit in the fixed amount of memory available for a variable, the in-memory value of a reference type is the reference itself (a memory address).

* Array
    
* Object
    
* Function
    

Reference types are also known as complex types or container types.

## Assigning by Reference

<mark>When a reference type value, an object, is copied to another variable using </mark> `=`<mark>, the address of that value is what’s actually copied over as if it were a primitive.</mark> **<mark> Objects are copied by reference</mark>** <mark> instead of by value.</mark>

```javascript
var reference = [1];
var refCopy = reference;
```

The code above looks like this in memory.

![](https://miro.medium.com/v2/resize:fit:875/1*d2W3ulHbHRGrFQ-c1SG5gA.png align="left")

<mark>Each variable now contains a reference to the </mark> *<mark>same array</mark>*<mark>. That means that if we alter </mark> `reference`<mark>, </mark> `refCopy` <mark> will see those changes:</mark>

```javascript
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
```

![](https://miro.medium.com/v2/resize:fit:875/1*RFrFRXIperg0yTwXauc97w.png align="left")

We’ve pushed `2` into the array in memory. When we use `reference` and `refCopy`, we’re pointing to that same array.

## <mark>Reassigning a Reference</mark>

Reassigning a reference variable replaces the old reference.

```javascript
var obj = { first: 'reference' };
```

In memory:

![](https://miro.medium.com/v2/resize:fit:875/1*PWGp9d2zZ_QGg18HXBSq9Q.png align="left")

When we have a second line:

```javascript
var obj = { first: 'reference' };
obj = { second: 'ref2' }
```

The address stored in `obj` changes. The first object is still present in memory, and so is the next object:

![](https://miro.medium.com/v2/resize:fit:875/1*1h73Wn9IyaiXbhxhmJZmYA.png align="left")

<mark>When there are no references to an object remaining, as we see for the address </mark> `#234` <mark> above, the Javascript engine can perform garbage collection. This just means that the programmer has lost all references to the object and can’t use the object any more, so the engine can go ahead and safely delete it from memory. In this case, the object </mark> `{ first: 'reference' }` <mark> is no longer accessible and is available to the engine for garbage collection.</mark>

# \== and ===

<mark>When the equality operators, </mark> `==` <mark> and </mark> `===`<mark>, are used on reference-type variables, they check the reference. If the variables contain a reference to the same item, the comparison will result in </mark> `true`<mark>.</mark>

```javascript
var arrRef = [’Hi!’];
var arrRef2 = arrRef;console.log(arrRef === arrRef2); // -> true
```

<mark>If they’re distinct objects, even if they contain identical properties, the comparison will result in </mark> `false`.

```javascript
var arr1 = ['Hi!'];
var arr2 = ['Hi!'];console.log(arr1 === arr2); // -> false
```

<mark>If we have two distinct objects and want to see if their properties are the same, the easiest way to do so is to turn them both into strings and then compare the strings. When the equality operators are comparing primitives, they simply check if the values are the same.</mark>

```javascript
var arr1str = JSON.stringify(arr1);
var arr2str = JSON.stringify(arr2);console.log(arr1str === arr2str); // true
```

---

# <mark>Passing Parameters through Functions</mark>

When we pass primitive values into a function, the function copies the values into its parameters. It’s effectively the same as using `=`.

```javascript
var hundred = 100;
var two = 2;function multiply(x, y) {
    // PAUSE
    return x * y;
}var twoHundred = multiply(hundred, two);
```

In the example above, we give `hundred` the value `100`. When we pass it into `multiply`, the variable `x` gets that value, `100`. The value is copied over as if we used an `=` assignment. Again, the value of `hundred` is not affected. Here is a snapshot of what the memory looks like right at the PAUSE comment line in `multiply`.

![](https://miro.medium.com/v2/resize:fit:875/1*3AYcflNTwTTGTgCul0DgBw.png align="left")

## <mark>Pure Functions</mark>

<mark>We refer to functions that don’t affect anything in the outside scope as </mark> *<mark>pure functions</mark>*<mark>. As long as a function only takes primitive values as parameters and doesn’t use any variables in its surrounding scope, it is automatically pure, as it can’t affect anything in the outside scope. All variables created inside are garbage-collected as soon as the function returns</mark>.

Let’s go into an example of a pure vs. impure function.

```javascript
function changeAgeImpure(person) {
    person.age = 25;
    return person;
}var alex = {
    name: 'Alex',
    age: 30
};var changedAlex = changeAgeImpure(alex);console.log(alex); // -> { name: 'Alex', age: 25 }
console.log(changedAlex); // -> { name: 'Alex', age: 25 }
```

Let’s look at a pure function.

```javascript
function changeAgePure(person) {
    var newPersonObj = JSON.parse(JSON.stringify(person));
    newPersonObj.age = 25;
    return newPersonObj;
}var alex = {
    name: 'Alex',
    age: 30
};var alexChanged = changeAgePure(alex);console.log(alex); // -> { name: 'Alex', age: 30 }
console.log(alexChanged); // -> { name: 'Alex', age: 25 }
```

### Test

```javascript
function changeAgeAndReference(person) {
    person.age = 25;
    person = {
        name: 'John',
        age: 50
    };
    
    return person;
}var personObj1 = {
    name: 'Alex',
    age: 30
};var personObj2 = changeAgeAndReference(personObj1);console.log(personObj1); // -> ?
console.log(personObj2); // -> ?
```

```javascript
console.log(personObj1); // -> { name: 'Alex', age: 25 }
console.log(personObj2); // -> { name: 'John', age: 50 }             
```

Remember that assignment through function parameters is essentially the same as assignment with `=`. The variable `person` in the function contains a reference to the `personObj1` object, so initially it acts directly on that object. Once we reassign `person` to a new object, it stops affecting the original.

This reassignment does not change the object that `personObj1` points to in the outer scope. `person` has a new reference because it was reassigned but this reassignment doesn’t change `personObj1`.

### Notes

All primitive datatype excepted null tested by typeof "typeof(null) == "object"".

#### Undefined

* A [`return`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return) statement with no value (`return;`) implicitly returns `undefined`.
    
* Accessing a nonexistent [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) property (`obj.iDontExist`) returns `undefined`.
    
* A variable declaration without initialization (`let x;`) implicitly initializes the variable to `undefined`.
    
* Many methods, such as [`Array.prototype.find()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) and [`Map.prototype.get()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get), return `undefined` when no element is found.
    

#### Null

`null` is used much less often in the core language. The most important place is the end of the [prototype chain](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) — subsequently, methods that interact with prototypes, such as [`Object.getPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf), [`Object.create()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create), etc., accept or return `null` instead of `undefined`.

`null` is a [keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords), but `undefined` is a normal [identifier](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers) that happens to be a global property.

### Difference between `null` and `undefined`

**Undefined** \-&gt; means that a var has been declared but has not yet been assigned a value.

**Null** \-&gt; is an assignment value it can be assigned to a var as a representation of nonvalue.

Undefined is a type itself, and null is an object.

```javascript
null = "value"; //Syntaxerror invalid left-hand side undefined value
```

```javascript
undefined = "value"; // non error
```

`undefined` means a variable has been declared but has not yet been assigned a value :

```javascript
var testVar;
console.log(testVar); //shows undefined
console.log(typeof testVar); //shows undefined
```

`null` is an assignment value. It can be assigned to a variable as a representation of no value :

```javascript
var testVar = null;
console.log(testVar); //shows null
console.log(typeof testVar); //shows object
```

From the preceding examples, it is clear that `undefined` and `null` are two distinct types: `undefined` is a type itself (undefined) while `null` is an object.

Proof :

```javascript
console.log(null === undefined) // false (not the same type)
console.log(null == undefined) // true (but the "same value")
console.log(null === null) // true (both type and value are the same)
```

and

```javascript
null = 'value' // Uncaught SyntaxError: invalid assignment left-hand side
undefined = 'value' // 'value'
```

In JavaScript we can have the following types of variables:

1. Undeclared Variables
    
2. Declared but Unassigned Variables
    
3. Variables assigned with literal `undefined`
    
4. Variables assigned with literal `null`
    
5. Variables assigned with anything other than `undefined` or `null`
    

The following explains each of these cases one by one:

1. **Undeclared Variables**
    
    * Can only be checked with the `typeof` operator which returns string **'undefined'**
        
    * Cannot be checked with the loose equality operator ( `== undefined` ), let alone the strict equality operator ( `=== undefined` ),  
        as well as **if-statements** and **ternary operators** ( `? :` ) — these throw Reference Errors
        
2. **Declared but Unassigned Variables**
    
    * `typeof` returns string **'undefined'**
        
    * `==` check with `null` returns `true`
        
    * `==` check with `undefined` returns `true`
        
    * `===` check with `null` returns `false`
        
    * `===` check with `undefined` returns `true`
        
    * Is **falsy** to **if-statements** and **ternary operators** ( `? :` )
        
3. **Variables assigned with literal** `undefined`  
    These variables are treated exactly the same as **Declared But Unassigned Variables**.
    
4. **Variables assigned with literal** `null`
    
    * `typeof` returns string **'object'**
        
    * `==` check with `null` returns `true`
        
    * `==` check with `undefined` returns `true`
        
    * `===` check with `null` returns `true`
        
    * `===` check with `undefined` returns `false`
        
    * Is **falsy** to **if-statements** and **ternary operators** ( `? :` )
        
5. **Variables assigned with anything other than** `undefined` or `null`
    
    * typeof returns one of the following strings: **'bigint'**, **'boolean'**, **'function'**, **'number'**, **'object'**, **'string'**, **'symbol'**
        

Following provides the algorithm for correct type checking of a variable:

1. Get the `typeof` our variable and return it if it isn't **'object'**
    
2. Check for `null`, as `typeof null` returns **'object'** as well
    
3. Evaluate [**Object.prototype.toString.call**](http://Object.prototype.toString.call)**(o)** with a switch statement to return a more precise value. `Object`'s `toString` method returns strings that look like **'\[object ConstructorName\]'** for native/host objects. For all other objects (user-defined objects), it always returns **'\[object Object\]'**
    

### [Number type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type)

Positive floating-point numbers between 2<sup>-1074</sup> ([`Number.MIN_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE)) and 2<sup>1024</sup> ([`Number.MAX_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE)) as well as negative floating-point numbers between -2<sup>-1074</sup> and -2<sup>1024</sup>.

Values outside the range ±(2<sup>-1074</sup> to 2<sup>1024</sup>) are automatically converted:

* Positive values greater than [`Number.MAX_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE) are converted to `+Infinity`.
    
* Positive values smaller than [`Number.MIN_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE) are converted to `+0`.
    
* Negative values smaller than -[`Number.MAX_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE) are converted to `-Infinity`.
    
* Negative values greater than -[`Number.MIN_VALUE`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE) are converted to `-0`.
    

The Number type has only one value with multiple representations: `0` is represented as both `-0` and `+0` (where `0` is an alias for `+0`). In practice, there is almost no difference between the different representations; for example, `+0 === -0` is `true`. However, you are able to notice this when you divide by zero:

```javascript
console.log(42 / +0); // Infinity
console.log(42 / -0); // -Infinity
```
