skull

Robert Tamayo

R
B
blog
skull

Weird Things in JavaScript

"Mastering" a programming language is more about understanding why things aren't working the way you expect them to work. A common example of this is when working with an array that is passed into a function as an argument. Inside the function, is the array the exact same array as was passed in, or is it a copy of it? Some languages give you a little control over this, such as PHP. Others, like JavaScript, are full of learning experiences. 

Here is the line I settled with today. This will make a copy of an array of objects, so any changes made to the original object will not affect the copy: 

setCachedFields(fields.map(field => Object.assign({}, field))); 

This is almost like a grammar problem. With all that fancy code, all I'm really trying to do is this: setCachedFields(fields) But of course, this is JavaScript, which passes arrays and objects by reference. So when I try to restore the fields array to the cachedFields value I created earlier, I find that I had been modifying the cached array all along. I thought that Object.assign() might work, so then I tried this: 

setCachedFields(Object.assign([], fields) 

But that had the same problem. It turns out the issue was not that while the reference to the array was new, the values of the array (the fields) were still Objects that referenced the same Objects in the original array. So finally, I did this:

setCachedFields(fields.map(field =>Object.assign({}, field})); 

That solves the problem by creating a clone of the “field” object before passing it into the array. 

This is the kind of problem we have with working in certain programming languages. There is some ambiguity in whether we are modifying the “actual” array (fields) or the cloned array (cachedFields). 

On the other hand, sometimes Object.assign is not necessary: 

let updatedFields = fields.filter(field => field != deletedField); 

That is all that was needed, whereas before I was using this mess: 

let updatedFields = Object.assign(
      [],
     fields.filter(field => field != deletedField),
); 
setFields(updatedFields);


Comments:
Leave a Comment
Submit