2

How is it possible, I'm creating a const to get the old messages from my chat, so I can know if has a new message comming from the database or something like that, but there is something wierd with my code, the const is changing value

const oldMessages = this.state.messages.slice();

// Console
console.log(oldMessages[oldMessages.length - 1]);
// Prints {name: "André", message: "asds", who: "Y", sending: true, local_key: 232, …}

newMessages.map((message, key) => {
    // Here I don't even call the const
    if (message.local_key != undefined) {
        const i = messages.map((i) => {
            return i.local_key
        }).indexOf(message.local_key);
        if (i >= 0) {
            // messages.splice(i, 1);
            messages[i].id = message.id;
            messages[i].sending = false;
            messages[i].local_key = null;
            newMessages.splice(key, 1);
            //
            // Limpar chave do banco
            //
        } else {
            newMessages[key].local_key = null;
        }
    }
    if (newMessages[key] != undefined) {
        newMessages[key].animate = true;
    }
});

// Console
console.log(oldMessages[oldMessages.length - 1]);
// Prints {name: "André", message: "asds", who: "Y", sending: false, local_key: null, …}

You can see, I don't even call the variables, except in the consoles

Has something to do with the reference?

PS: messages is a reference of this.state.messages too

SpaceDogCS
  • 2,808
  • 3
  • 20
  • 49

2 Answers2

4

const doesn't do what you think it does.

const prevents re-assigment of a variable:

const arr = []; 

arr.push(1); // works

console.log(arr); // [1]

arr = []; // whoops
Marco
  • 7,007
  • 2
  • 19
  • 49
  • Interesting, I didn't know that, but I dont mutate the variable in the code, it's being mutated by the reference? I mean, `b = 1; const a = b; b = 2` it will change the value of a? – SpaceDogCS Feb 09 '18 at 12:08
  • 1
    You have to know that objects in javascript are always passed as references. So: `const obj = {hello: 1}; const arr = [obj]; const newArray = arr.slice(); newArray[0].hello = 1337;` will in fact change `obj`. – Marco Feb 09 '18 at 12:11
  • How can I prevent it? – SpaceDogCS Feb 09 '18 at 12:11
  • @SpaceDogCS You have to copy the object completely. – Marco Feb 09 '18 at 12:12
  • Like this https://stackoverflow.com/questions/12690107/clone-object-without-reference-javascript – SpaceDogCS Feb 09 '18 at 12:16
3

One thing to know about const is that

Constants are block-scoped, much like variables defined using the let statement. The value of a constant cannot change through re-assignment, and it can't be redeclared.

In your case you are not reassigning the const variable, but mutating its original value which is possible

What you are looking for is an Immutable data which doesn't change it value but creates a new reference of the original data and updates it. Look into libraries such as Immutable-JS

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Interesting, I didn't know that, but I dont mutate the variable in the code, it's being mutated by the reference? I mean, `b = 1; const a = b; b = 2` it will change the value of a? – SpaceDogCS Feb 09 '18 at 12:07
  • 2
    @SpaceDogCS, no It wont because number and strings are Immutable in javascript – Shubham Khatri Feb 09 '18 at 13:43