DEV Community

Mateusz Janusz
Mateusz Janusz

Posted on

JS Concepts: Value vs. Reference

This article is a part of a series covering fundamentals of the JavaScript language. The intention of this series is to help developers advance their knowledge and really understand how the JavaScript language works. And to help myself get better at writing ๐Ÿ˜‰


In the previous article, we talked about call stack. Today, we're going to discuss the difference between value and reference in JavaScript. At the end of this article, you will be able to tell why primitives and objects behave differently and how to avoid mistakes while manipulating them. ๐Ÿ’ช

Types in JavaScript

In JavaScript we have two categories of types.

Value types (primitives)

Types that are passed by value:

  • String
  • Number
  • BigInt
  • Boolean
  • Symbol
  • undefined
  • null

Reference types

Types that are passed by reference:

  • Object
  • Array
  • Function

Let's have a closer look at both of them.

Value vs. Reference

When you assign a variable, the JavaScript engine decides whether the value is a primitive or a reference value.

Primitive

When we assign a value as primitive, the value is actually stored in the variable. This means that when you manipulate the variable, you are working on the actual value stored in the variable. If you assign primitive variables to other variables using =, their values are copied to new variables. We say that they are copied by value.

Reference

When we assign non-primitive value to the variable, we copy them by reference. In other words, variables are given a reference to that value, so they donโ€™t actually contain the value.

When you assign a non-primitive variable to other variable using =, its reference is copied to the new variable and so they now both point to the same objectโ€™s location in memory. Consequently, if you decide to manipulate only one of them, you are actually working on the reference, which means you manipulate both variables!

This is crucial to understand as itโ€™s often the reason behind bugs.

Examples

Primitive values

const a = 5
let b = a

console.log(a) // 5
console.log(b) // 5

b = 10

console.log(a) // 5
console.log(b) // 10
Enter fullscreen mode Exit fullscreen mode

As you can see in the example above, the value stored in the variable b has been changed, but the value of variable a remains intact. This is because variables a and b have no relationship. By copying value from variable a to b, we created a new independent value.

let index = 0

function increaseIndex(index) {
    index++
}

increaseIndex(index)
console.log(index) // 0
Enter fullscreen mode Exit fullscreen mode

The index value stays 0 even after executing increaseIndex function. This is because primitive values are copied by value. We're dealing with two independent values here, so changing the copied value has no effects on the original value.

Non-primitive values

const person_one = {
    name: 'Adam',
    age: 20
}
const person_two = person_one

console.log(person_one.name) // 'Adam'
console.log(person_two.name) // 'Adam'

person_two.name = 'George'

console.log(person_one.name) // 'George'
console.log(person_two.name) // 'George'
Enter fullscreen mode Exit fullscreen mode

By changing the name of person_two, we're also modifying value in person_one because both person_one and person_two are pointing to the same object. When the variable person_two is created and assigned to person_one, we're creating an alias to the original object, not a new object.

const person = {
    name: 'Adam',
    age: 20
}
function changeName(person) {
    person.name = 'George'
}

changeName(person)
console.log(person.name) // 'George'
Enter fullscreen mode Exit fullscreen mode

In this case, the person name was changed after executing changeName function. This is because when we pass an object into the function, we're passing a reference to that object. When we change a property of that object within the function, the change will be reflected in the outer scope.

Summary

  • Primitives are copied by their value
  • Objects are copied by their reference
  • When you manipulate variable that stores a primitive value, you are working on the value stored in the variable
  • When you manipulate an object, you are working on the reference to that object, not on the actual object





This article was originally published on my personal blog mateuszjanusz.dev.

Top comments (3)

Collapse
 
aleksandrhovhannisyan profile image
Aleksandr Hovhannisyan

When we assign non-primitive value to the variable, we copy them by reference. In other words, variables are given a reference to that value, so they donโ€™t actually contain the value.

This actually isn't true. The assignment operator assigns a value in all cases (for both objects and primitives). In the case of objects, the "value" is a memory address (a pointer). Learn more on that here in an article I wrote: Is JavaScript Pass by Reference?. This is how Chrome's v8 engine works, for exampleโ€”the "references" are really just pointers under the hood.

Collapse
 
jonrandy profile image
Jon Randy ๐ŸŽ–๏ธ

Missed BigInt

Collapse
 
mateusz_janusz profile image
Mateusz Janusz

Thank you, fixed it!