How do value types and reference types work in Javascript?

Asked

Viewed 4,778 times

16

I know that in C# there are value types and reference types and one of the differences between them is in memory management. What decides how the variables will behave is their type, so if it’s a int will be value type, if it is instance of a class Cliente, for example, it will be a reference type.

Javascript has no difference of types. All variables are instantiated with the keyword var. So how does memory management work in Javascript? There is this difference, of some variables being stored directly in the stack and others being stored in the heap only having a reference on the stack?

  • 1

    Its definition of C# has become somewhat vague. The difference between reference and value types is basically the statement. structs are value, classes are reference.

  • Take a look at this material. It has information about language regarding memory management. I think that’s what you want to know. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management?redirectlocale=en-US&redirectslug=JavaScript%2FMemory_Management

  • 1

    Yes, I know @Andréleria, I just quoted an example. Thanks for completing.

  • 1

    I didn’t mean to be rude, just clarify it. Your example was good anyway.

4 answers

15


Javascript has no difference of types. All variables are instantiated with the keyword var.

Javascript has a type system

When you store a value in a variable, that value has a type. The type of a given value never changes, but the value stored in a variable can be changed. Any variable can contain a value of any type at any time, and so it makes no sense to declare the type of the variable. Type is a characteristic of values, and variables (think of them as places where values are stored) are agnostic about them. In other words, variables are not tied to any type, but always contain values that belong to some of the available types.

The guys

Five of the six Javascript types have values primitive: Undefined, Null, Boolean, String and Number. Primitive values like undefined, null, true, "texto" and 10 are immutable. Undefined and Null are special types that have only one value each, respectively undefined and null.

The sixth type is Object, which includes arrays, functions, and others. Objects are sets of properties, which can hold values of any of the above types. Properties can be added to an object or removed from it at any time, and property values can also be changed. Therefore, objects are changeable.

There are also other types that the specification defines for own use, to describe how the language should work. They are not available to language users (nodes), nor need direct correspondents in the implementation.

Valor versus reference

I don’t know the C#, but from what I understand about value types and Reference types, it is possible to draw a parallel with Javascript. Set aside the question of the allocation location, which I will discuss later, and focus on the behavior of types when a value is assigned to a variable or passed to a function or method.

It can be considered that the primitive types of Javascript function as the value types, while the objects function as the Reference types. I will explain with an example:

var meuObjeto = {};

Here you create an object, which is stored in the variable meuObjeto. But is it? What is stored in this variable is a value of the Object type. The object itself (with its properties, methods, etc.) is stored somewhere in memory, managed by the language interpreter. And the value of the Object type is a reference to that object.

To say that objects are references means only that with the reference at hand you can access the object, and nay that the reference is a pointer to where the object is stored in memory. This distinction is very important. Think of the reference as a value like any other. Now consider the following example:

var a, b;
a = {};
b = a;
b.umaPropriedade = "um valor";
b == a; // true
a.umaPropriedade; // "um valor"
b = { outroObjeto: true };
b == a; // false

Here, b is not "a reference to a"; b contains a reference to a particular object, and a contains another reference to the same object. Thus, one can change a property of the same object by means of a or b. But you can’t overwrite the object that’s in a by assigning a new value to b. What b = { outroObjeto: true } does is only store in b a new reference to another object. The first object continues to exist, and the reference contained in a still points to him.

This same concept also serves to understand how objects are passed to functions:

function teste(obj) {
    obj.novaProp = "foo";        // o objeto fora da função é afetado
    obj = { outraProp: "bar" };  // o objeto fora da função NÃO é afetado
}
var o = {};
teste(o);
o.novaProp;  // "foo"
o.outraProp; // undefined

This means that in Javascript there is no "by reference" passage. The object is passed by value, only the value passed in teste(o) is a reference.

So how does memory management work in Javascript? There is this difference, of some variables being stored directly in the stack and others being stored in the heap only having a reference in the stack?

When programming in Javascript, keep in mind that access to memory is in charge of the language interpreter. You don’t manipulate the memory directly in Javascript. The language specification does not even mention how memory should be treated, this is entirely in charge of the implementation. Therefore it is not possible to say where each data is stored without knowing well how each interpreter works. I don’t know that, so I can’t say anything about.

But if you’re worried about using memory by your Javascript, remember the following:

  • There is a Garbage Collector us Engines javascript
  • That one Garbage Collector is executed at arbitrary times (usually when the interpreter is not busy with its code)
  • The Garbage Collector only release the memory occupied by an object if there is no "live" reference to that object.
  • That is: beware of objects captured in closures, they may end up occupying memory eternally!

The doubts I had when preparing and finalizing this answer generated a question on Soen, with a very interesting answer.

  • When you say arbitrary, is it arbitrary (I’ve seen cases) or is it not deterministic? Just being boring, it can vary according to implementation. I think that part of closure keeping the object eternally is true, but it is not the fault of closure and yes where it was used.

  • I meant that from the programmer’s point of view it seems arbitrary/random, it’s out of his control. But in practice I believe it’s deterministic in most cases, right? About closures, it’s kind of loose even what I said, it was more of a tip because the careless use of closures is one of the main causes of memory Leaks in js.

  • In JS I do not know, and I think it should depend on the implementation. In C# it is not deterministic, but it is not arbitrary. There is a way not to trigger a collection. Never make an allocation, because it is in the allocation that can trigger the collection, and only if you reach a certain criterion. I’ve seen GC which is arbitrary, it fires at "any" moment. In C# not important whether you are doing something important or not, it fires when you need to release memory in the established criteria, nothing else is looked at. I don’t know if JS has protected areas.

9

Javascript has a difference between data types yes, despite being a language of weak typing. You can find the types of data that javascript supports here.

Therefore, Javascript does not allow the passage of values by reference, but it is possible to circumvent this limitation by passing an object as parameter, as can be seen in the following example:

var A = new Array();

function swap(A, a, b){
        var c = A[a];
        A[a] = A[b];
        A[b] = c;
}

And in addition to being weakly typed, like most scripting languages, Javascript has dynamic typing, which, along with being weakly typed, makes the language more dynamic.

  • 2

    So, numbers, booleans, strings, null and Undefined are like the value types of C#, stored directly in the stack while objects are like the reference types, created in the heap containing references in the stack? Thank you.

  • 1

    Basically, yes.

3

In Javascript there are types Primitive and types Complexes.

Primitives would be string, number, Boolean and Undefined. Primitive types are copied by value. So:

var x = 1, y = x;
x = 2;
console.log(x);//vai mostrar 1

Complexes are Objects, functions and arrays. Complex types are copied by reference. So:

var x = [1,2], y = x;
y[0] = 3;
console.log(x);//vai mostrar [3,2]

So I guess it looks like C#.

Reference: https://github.com/airbnb/javascript#types

1

Javascript is a "weakly typed language".

The type of the variable is determined by the interpreter at runtime and can be changed during the execution of the program as the contents of the variable is changed.

Several languages that are defined this way, mainly languages interpreted as javascript.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.