Why is it allowed to delete elements from an array defined as const?

Asked

Viewed 603 times

10

Assuming I have set an array to const:

const array = [1,2,3]

Why is it possible for one of these elements to be removed? This would not be a way to reassign the array?

It’s possible I’ll make one:

array.pop()

And then my array would no longer be the same as the one initially defined. If the goal of the constant is to make it clear that its value cannot change because deletion of items in the array is allowed?

  • 1

    Because when you create a constant, you’re informing that you don’t want there to be a reallocation*, that is, it is not possible to do something like array = [1, 2]. If you want to prevent the structure from being modified, then you are looking for immutable data structures.

  • 1

    To summarize, the object does not change when it uses array.pop, only changes the content within it, you could create a class and "instantiate it" right in the const and then take one of the property and set a new value const = new foo; foo.x = 1. The instance remains the same. Vale remembers that the property values of an object function as a reference, but the value itself applied to a variable or constant does not.

3 answers

14


As stated in summary section of the documentation of const:

To statement const creates a variable whose value is fixed, that is, a read-only constant. This does not mean that the value is immutable, only that the constant variable cannot be changed or re-assigned.

This means that you cannot create another variable with the same name, since a read-only reference has been created. However, you can still change the value of the constant.

This is clearly visible in objects:

// Note `const`:
const person = { name: 'Fulano' };

console.log(person.name);

// O valor que a variável armazena pode ser alterado.
// Só não pode ser reatribuído.
//
// Então isso está OK:
person.name = 'Luiz Felipe';

console.log(person.name);

Or in arrays, as per your example.


If you want to create a really immutable object, you can use the Object.freeze, that "freezes" past reference. For example:

const arr = [1, 2, 3];
Object.freeze(arr); // A partir de agora, `arr` está "congelada".

const obj = { name: 'Luiz Felipe' };
Object.freeze(obj); // A partir de agora, `obj` está "congelado".

But why does it really happen?

Every Javascript object has its properties (this is not new to us), the thing is that each of these properties has some so-called "metadata" Property Descriptors, that configure the behavior of that specific property. These Property Descriptors have some attributes, are they:

  • configurable, that will be true (true) if the property can be changed and deleted from its object.
  • writable, which will be true if the property can be changed using some allocation operator.
  • enumerable, which will be true if the property is shown during the enumeration of its object. For example, in Object.keys or in bonds for..in.
  • value, representing the value associated with the property in question.

The documentation gives a good idea about this. There’s also the question "What and how Javascript property descriptors and attributes work?", which summarises their operation.

Thus, whenever you create a literal object, all its properties have their descriptors defined with enumerable, configurable and writable defined as true. This means that every literal created object can have its properties changed, deleted and the like.

So when you use the Object.freeze, object properties will have their descriptors changed to define enumerable and writable as false. The object will also suffer extension prevention, which will not allow new properties to be added to it. Essentially, the Object.freeze makes any object truly immutable.

We can observe this behavior using the Object.getOwnPropertyDescriptors. Behold:

const obj = { name: 'Luiz Felipe', username: 'lffg' };

// Note na saída que cada propriedade (`name` e `username` do objeto `obj`)
// possui os descritores `writable` e `configurable` definidos como `true`.
console.log(Object.getOwnPropertyDescriptors(obj));

console.log('====== Congelou ======');
Object.freeze(obj);

// Note agora que os descritores `writable` e `configurable` estão como `false`.
console.log(Object.getOwnPropertyDescriptors(obj));

And the same goes for arrays, since in Javascript, all array is an object, and roughly, the indices are the "properties". Therefore, the behavior is exactly the same:

const arr = [1, 2, 3];

// Note na saída que cada índice (`0`, `1` e `2` do array `arr`)
// possui os descritores `writable` e `configurable` definidos como `true`.
console.log(Object.getOwnPropertyDescriptors(arr));

console.log('====== Congelou ======');
Object.freeze(arr);

// Note agora que os descritores `writable` e `configurable` estão como `false`.
console.log(Object.getOwnPropertyDescriptors(arr));


Finally, I want to make it clear that it is not the statement const defining writable and configurable as true by default. It is the fact that you create the object using the literal form. You can create "fully configured" objects using the method Object.create. The Object.defineProperty allows you to create one property configured at a time. And finally, the Object.defineProperties allows you to create multiple properties configured at once.

But don’t worry about all that. This is more related to metaprogramming. Are rarely used directly.

7

We can declare a variable as constant through the const keyword. But what is a constant ? Once a value has been assigned to a variable that has been declared using the const keyword, its value cannot be changed. For this reason, all constants must be initialized in the declaration. For example:

// constante válida
const idade = 18;

// constante inválida: onde está a inicialização ?
const pi;

In the above code we have the example of an age constant being declared and initialized on the same line (valid constant) and another example where the value is not assigned in the declaration (invalid constant). In addition, constants also have block scope, as well as variables declared with the keyword Let. What happens if we try to change the value of a constant variable? Let’s test:

const idade = 18;
idade = 21;

If we try to run the above code, an error will be thrown: constants cannot have their value changed.

  • Above, we explain how the use of Constants is made. Now, below we will see the following reasons that may cause the change of a constant (which was to be immutable). Behold:

One of the reasons can be your browser version.

In previous versions of Firefox & Chrome and from Safari 5.1.7 and Opera 12.00, if you set a variable with const, you can still change the value later. This feature is not supported in Internet Explorer 6-10, but is included in Internet Explorer 11.

inserir a descrição da imagem aqui

We also have another approach:

Nonreal constants:

The const keyword is a bit misleading. DOES NOT define a constant value. It defines a constant reference to a value.

For this reason, we cannot change primitive constant values, but we can change the properties of constant objects.

PRIMITIVE VALUES:

If we assign a primitive value to a constant, we cannot change the primitive value:

Example:

const PI = 3.141592653589793;
PI = 3.14; // Isso dará um erro
PI = PI + 10; // Isso também dará um erro

CONSTANT OBJECTS CAN CHANGE

You can change the properties of a constant object:

EXAMPLE:

// Você pode criar um objeto const:
const carro = {type:"Fiat", model:"500", color:"white"};

// Você pode alterar uma propriedade:
carro.color = "red";

// Você pode adicionar uma propriedade:
carro.owner = "Jason";

But you can’t reassign a constant object:

EXAMPLE:

const car = {type:"Fiat", model:"500", color:"white"};
car = {type:"Volvo", model:"EX60", color:"red"};    // ERRO

CONSTANT MATRICES MAY CHANGE

You can change the elements of a constant matrix:

EXAMPLE:

// Você pode criar uma matriz constante:
const carros = ["Saab", "Volvo", "BMW"];

// Você pode alterar um elemento:
carros[0] = "Toyota";

// Você pode adicionar um elemento:
carros.push("Audi");

But you CANNOT reassign a constant matrix:

EXAMPLE:

const carros = ["Saab", "Volvo", "BMW"];
carros = ["Toyota", "Volvo", "Audi"];    // ERRO

References:

http://www.matera.com/

https://developer.mozilla.org/en-US/

w3schools.com

7

Its array and the objects contained in it have no connection. The array is just an object, or rather, a memory address that holds other objects inside it.

The definition const serves so that the value assigned to the constant does not change, that is, it does not let us change the constant of an array to a string and not even create a new array object. In the code below for example, an error will be generated because in the second line I try to change the object assigned to the constant to a new object.

const array = [1, 2, 3];
array = [1, 2, 3];

For that very reason too, it is obligatory you initialize the constant in your statement, because once you have its value assigned, it cannot be changed.

But still, you can add, remove, or change the properties of Javascript objects, including arrays:

const array = [1, 2, 3];
array.length = 5;                 // Alterando a propriedade do objeto.
array.name = "Array de números"   // Adicionando uma nova propriedade.

Browser other questions tagged

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