DEV Community

Naba Zehra
Naba Zehra

Posted on

Value vs Reference

Primitives vs Objects

In the previous chapter, we learned why changing copy can unexpectedly change user.

The reason was simple:

Both variables were pointing to the same object in memory.

But that raises an interesting question.

Why does this happen with objects, but not with strings?

Take a look at this example:

let firstName = "Aline";
let copy = firstName;

copy = "Ali";

console.log(firstName);
Enter fullscreen mode Exit fullscreen mode

What do you think the output will be?

If you said:

"Aline"
Enter fullscreen mode Exit fullscreen mode

you're absolutely right.

Changing copy doesn't affect firstName.

Now compare that with an object:

const user = {
  name: "alina"
};

const copy = user;

copy.name = "Ali";

console.log(user.name);
Enter fullscreen mode Exit fullscreen mode

This time the output is:

"Ali"
Enter fullscreen mode Exit fullscreen mode

Wait a second.

Why are these examples behaving differently?

In both cases we created a copy.

In both cases we changed the copy.

Yet one leaves the original value untouched, while the other changes it.

At first glance, JavaScript seems inconsistent.

But once you understand the difference between primitive values and objects, everything starts to make sense.

Let's investigate.


Meet the Primitive Values

Before We Continue, What Does "Primitive" Actually Mean?

We've been using the word primitive, but what does it actually mean?

In simple terms, a primitive is a single value.

It isn't made up of smaller values.

For example:

const name = "Aline";
Enter fullscreen mode Exit fullscreen mode

Each variable contains one simple value

A string.

A number.

A boolean.

Nothing more.

Types

JavaScript has seven primitive types:

These include:

String
Number
Boolean
Undefined
Null
Symbol
BigInt
Enter fullscreen mode Exit fullscreen mode

These values are simple.

JavaScript can store them directly.

When we write:

let a = "alina";
let b = a;
Enter fullscreen mode Exit fullscreen mode

JavaScript copies the actual value.

a ───► "alina"
b ───► "alina"
Enter fullscreen mode Exit fullscreen mode

Notice something important.

Both variables have their own copy.

There is no connection between them.

So when we execute:

b = "Ali";
Enter fullscreen mode Exit fullscreen mode

JavaScript simply changes the value inside b.

a ───► "alina"
b ───► "Ali"
Enter fullscreen mode Exit fullscreen mode

Nothing happens to a.

This behavior is called copy by value.


Objects Play By Different Rules

Now let's revisit our earlier example.

const user = {
  name: "Alina"
};

const copy = user;
Enter fullscreen mode Exit fullscreen mode

Unlike strings and numbers, objects are not copied directly.

Instead, JavaScript copies a reference.

user ───► Object

copy ───► Same Object
Enter fullscreen mode Exit fullscreen mode

Both variables point to the same object.

That's why changing the object through one variable affects the other.

copy.name = "Ali";
Enter fullscreen mode Exit fullscreen mode

The object changes.

Since both variables point to it, both variables see the update.

This behavior is called copy by reference.


A Simple Rule To Remember

Whenever you're confused, ask yourself one question:

Am I working with a primitive value or an object?

If it's a primitive:

const a = "Hello";
const b = a;
Enter fullscreen mode Exit fullscreen mode

JavaScript copies the value.

If it's an object:

const a = {};
const b = a;
Enter fullscreen mode Exit fullscreen mode

JavaScript copies the reference.

Meet the Second Category: Non-Primitive Types Or Objects

So far, we've talked about primitive values.

But not every value in JavaScript is a primitive.

Whenever you need to store multiple pieces of information together, JavaScript gives you objects.

const user = {
  name: "Alina",
  age: 15
};
Enter fullscreen mode Exit fullscreen mode

Unlike primitives, objects can contain multiple values and even other objects.

Arrays and functions also belong to this category.

const skills = ["JavaScript", "React"];

function greet() {
  console.log("Hello");
}
Enter fullscreen mode Exit fullscreen mode
console.log("typeof skills",typeof skills)
console.log("typeof greet",typeof greet)
console.log("greet",greet instanceof Object)
Enter fullscreen mode Exit fullscreen mode

Output

Object
function
true
Enter fullscreen mode Exit fullscreen mode

At this point, we've uncovered something interesting.

Functions aren't just pieces of code that can be executed.

They're also objects.

function greet() {}

console.log(greet instanceof Object); // true
Enter fullscreen mode Exit fullscreen mode

That might seem strange at first, but it opens the door to some fascinating questions.

How can something be both a function and an object?

What special powers do functions have that regular objects don't?

And why does JavaScript treat them differently?

Let's find out.

In the next chapter, we'll take a closer look at functions and discover what actually makes them special.

Top comments (0)