What JS variables and C pointers have in common?
Published: 2023-12-01 20:04:03

Hello! I'm a frontend developer, who is actually studying DSA using C. The reason? C was my first language, and it's an awesome language.

Going into the point: JavaScript variables have a different behavior while dealing with some primitive values and while dealing with some non-primitive values like object. Since primitive values are immutable, we can't work with references for them.

```javascript
const val1 = 10;
let val2 = val1; // this will copy the value
val2 = 25;

console.log(val1); // 10
console.log(val2); // 25
```

As you can verify in the example above, when dealing with primitive values, an assignment to the new variable will not create a reference, rather this will copy the value from the variable on the right side of the expression into the variable on the left side. This works the same way in C.

```c
#include <stdio.h>

int main(int argc, char *argv[])
{
  int val1 = 10;
  int val2 = val1; // copy value
  val2 = 25;

  printf("%i \n", val1); // 10
  printf("%i \n", val2); // 25
  return 0;
}
```

But what happens when we go to a more complex type, like object? Let's see

```javascript
const obj1 = {
  key: 1,
};
const obj2 = obj1;
obj2.key = 2;

console.log(obj1) // { key: 2 }
console.log(obj2) // { key: 2 }
```

You may be asking, "why the assignment in obj2 changes the value for obj1 too?". The answer to this question is REFERENCE. Essentially, obj2 receives a reference to the place obj1 is in memory. This means that obj2 will not copy the value from obj1, instead both objects are pointing to the same place in memory, in other words they are the same reference. How can we replicate this behavior in C? Let me show:

Wrong example

```c
#include <stdio.h>

typedef struct
{
  int key;
} ELEMENT;

int main(int argc, char *argv[])
{
  ELEMENT val1, val2;
  val1.key = 1;
  val2 = val1;
  val2.key = 2;

  printf("%i \n", val1.key); // 1
  printf("%i \n", val2.key); // 2
  return 0;
}
```
In the example above, we can see that val2 copy the value of val1. But why val2 just didn't copy the reference to val1? Because in C we have a thing called pointer. Pointers store the memory address of other variables, instead of copying the values. Let me show:

Correct Example

```c
#include <stdio.h>

typedef struct
{
  int key;
} ELEMENT;

int main(int argc, char *argv[])
{
  ELEMENT val1, *val2;
  val1.key = 1;
  val2 = &val1;
  val2->key = 2;

  printf("%i \n", val1.key);  // 2
  printf("%i \n", val2->key); // 2
  return 0;
}
```
With the code above, we replicate the example of the last JavaScript code. As we can see, in the expression `val2 = &val1;` we're copying the memory address from val1, to val2. This is essentially what JS does when dealing with objects, and that's the reason we can't compare objects directly. If we print the memory address from val1 and val2, we would get the following prints:

```c
  printf("%p \n", &val1); // 0x16d102d4c
  printf("%p \n", val2);  // 0x16d102d4c 
```

To check in C if the pointer has the same address as the variable, we can compare using the following expression: `if(&val1 == val2) { //...do some stuff }`. This is essentially what JS is doing behind the scenes while comparing two objects. It's not comparing the values that both objects are pointing, rather it's comparing their addresses.

Let's see an example of this:

```javascript
  const obj1 = { key:1 };
  const obj2 = { key:1 };
  
  console.log(obj1 === obj2); // false - unequal references

  const obj3 = obj1;
  console.log(obj1 === obj3); // true - same references
```

I hope that this short article helps you to understand a little bit of how references works in JavaScript. Thanks for reading!