0

What is the reason why Javascript push objects by reference and not by value?

And why this behavior is only for objects and not also for built-in primitives types?

For example:

let x = {a: 10, b: 100 }
let ar = [];

ar.push(x);
x.a = 9;
console.log(ar[0].a); // This print 9, not 10

I think an answer to this question is useful to understand some deep functions about this language.

Thanks in advance.

Stefano
  • 179
  • 2
  • 13
  • 3
    Everything in Javascript, not only primitives, is passed by value. – Gerardo Furtado Dec 30 '19 at 00:50
  • @GerardoFurtado check this post: [Do objects pushed into an array in javascript deep or shallow copy?](https://stackoverflow.com/questions/8660901/do-objects-pushed-into-an-array-in-javascript-deep-or-shallow-copy/8661088#8661088) – Stefano Dec 30 '19 at 00:53
  • 4
    I know this, thanks anyway. It's still by value... It's complicated at first, I agree. – Gerardo Furtado Dec 30 '19 at 00:56
  • 1
    It's very difficult to do otherwise and still maintain some standard sense of object orientation. If values were immutable and functions were free of side-effects, then this would be reasonable -- but then you're much of the way toward functional programming. Javascript makes it easy enough to do OOP, and possible, but less easy to do FP; that was one of the essential design decisions of the language. – Scott Sauyet Dec 30 '19 at 01:01

1 Answers1

3

Everything in JavaScript is passed by value...

But, those values can be a reference value.

The different seems subtle, but its very important.

For example, if you have a function:

function nukeArray(a) {
  a = [];
}

Then, when you call it, a will receive a value that happens to be a reference. That value is immediately discarded and a is assigned a new reference.

If a was a pure reference, then changing a would also change the value of its caller.

In a language like C you can easily pass a reference -- change the reference -- then the caller's value will be changed as well.

#include <stdio.h>
#include <stdlib.h>

void t(char **t) {
    *t = malloc(50);
}

int main() {
    char *tmp;
    printf("pre: %p\n", tmp);
    t(&tmp);
    printf("post: %p\n", tmp);
}
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • Your explanation is clear. But what about my example? If I change `x` object it will change also `ar[0]`. Isn't it like it's a reference? – Stefano Dec 30 '19 at 01:37
  • 2
    Yes, it s a reference. But a `reference value` -- meaning, it passes a value and that value is a reference. This is *different* from passing by reference. The real reason why you don't pass an object (or array) by value is that making a copy of that object would get expensive, which would slow down your program. – Jeremy J Starcher Dec 30 '19 at 01:47
  • 1
    @Stefano if you don't want a reference to the original object you can always clone it (a shallow copy, probably) and push the cloned object. – Gerardo Furtado Dec 30 '19 at 01:49