What is the proper way to add an object to an array without cloning or passing it by reference?

My issue is with a property called 'tiles' in a class that holds information about the state of a checkers board game. Each time I make a legal move or start the game, I want to push this property to an array named 'moves'. However, the problem arises when pushing the new tiles property causes the previous elements in the moves array to change to the values of the most recently pushed tiles.

I realize this is happening because the object is passed by reference, which results in replacing old elements in the array since they all point to the same object - the latest value of the tiles property. Is there a way to push each different individual state of 'tiles', resulting from legal moves, rather than by reference as my code currently does?

Take a look at my snippet below: App.js

App = function () {
  var self = this;
  self.tiles = []; 
  // Objects are populated from a JSON file
  // Code to fetch JSON and save it to self.tiles
  // More code

  this.startGame = function () {
    // Other code
    self.moves.push(self.tiles);
  };
  this.makeMove = function () {
    // Other code
    self.moves.push(self.tiles);
  };
};

What I am expecting is for the objects in the self.moves array to point to different objects instead of the same one. The array should hold different states of self.tiles, but currently, every time I push the property, the elements in the 'moves' array are overwritten by the latest value of self.tiles.

Any assistance in resolving this issue would be greatly appreciated. Thank you!

Answer №1

For creating a clone of a nested object, it is recommended to utilize JSON.parse(JSON.stringify()). When dealing with shallow objects, you can opt for using Object.assign.

App = function () {
  var self = this;
  self.tiles = []; 
  // This array gets populated with objects from a JSON file
  // Code snippet to fetch the JSON data and save it to self.tiles
  // More code

  this.startGame = function () {
    // Other functionality
    self.moves.push(JSON.parse(JSON.stringify(self.tiles)));
  };
  this.makeMove = function () {
    // Additional functionality
    self.moves.push(JSON.parse(JSON.stringify(self.tiles)));
  };
};

Answer №2

After experimenting with it for some time, I discovered a handy trick using the spread operator:

let obj = {x: 10, y: 20}
let array1 = []

array1.push({...obj})
obj.y = 30

console.log(array1) // [0: {x: 10, y: 20}]
console.log(obj) // {x: 10, y: 30}

Learn more about spreading in object literals on MDN

Answer №3

To effectively handle the problem at hand, it is essential to provide a clone of the object that needs to be added to the vector. In similar situations, it is common practice to implement a clone() function for your object that yields a thorough duplicate of itself. Subsequently, the resulting object from this function call can be inserted into the array.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to produce a random integer within the range of 0 and 2

Here is the code snippet: var i = prompt('Please choose Rock, Paper or Scissors:'); var b = ['Rock', 'Paper', 'Scissors']; Now, I need help in generating a random number between 0-2. My initial idea was to do t ...

Creating an environment variable using the package.json script

I'm trying to set the process.env.ENV variable as either TEST or null using a script in my package.json file. The command below is not working when I run it through package.json (though it works fine when directly executed in cmd). script { "star ...

Utilizing Firebase 9.0.1 Functions in Vue.js 3

As a newcomer to Vue, I decided to tackle my second tutorial which involved integrating Firebase backend with Vue. However, the tutorial was based on Vue 2 and an older version of Firebase. Determined to stay current, I set out to replicate the project usi ...

Transmit data via AJAX to the RequestBody

Although seemingly simple, this issue has proven to be quite challenging. I am confident that it can be easily resolved, but the solution continues to elude me. Thank you for any assistance you can provide. Here is the code snippet in question : var samp ...

Is the shift key being pressed during the onClick event in React?

To trigger an onClick event only when the meta(mac) / ctrl(win) key is pressed, follow these steps: This is what I attempted: const [shiftOn, setShiftOn] = useState(false) useEffect(() => { document.addEventListener('keydown', (e) => ...

Using AJAX in Django to detect fields with JavaScript

I am currently working on a model: class Name(models.Model): name = models.CharField(max_length=255) project = models.CharField(max_length=255) story = models.CharField(max_length=500) depends_on = models.CharField(max_length=500, ...

Is there a way to access the sqlite3 database file in electron during production?

Currently, I have an electron application that I developed using the create-electron-app package. Inside the public folder of my Electron app, both the main process file and the sqlite3 database are located. During development, I can access the database ...

unable to update database using jquery ajax

Hello everyone, this is my first time posting on Stackoverflow! I am facing an issue while trying to run an "Insert" query using Jquery's $.ajax function. Upon checking the network tab on Chrome Dev Tools, it seems like my file is being loaded but th ...

AngularJS - Setting an initial delay for ng-bind

We have a span element with the following attributes: <span role="link" ng-show="showLink()" ng-bind="textLink"></span> (Just an fyi: we implemented a fade-in, fade-out animation for this link, hence the use of ng-show instead of ng-if) The ...

Is it possible to refresh text in table without clearing icons?

Is there a way to maintain icons in table rows when editing text fields from a dialog? Currently, regardless of whether I use .html() or .text(), the icons disappear. I suspect that utilizing .content() may be a solution, but I'm unsure how to impleme ...

Adding schemas to the router of a Next.js 13 app is a helpful feature that can

Summary: In Next.js 13, the /app router's new changes to layout and page routing have altered how we add content to the <head>. The challenge now is how to include a schema script on each page. Next.js automatically combines <head> tags f ...

Problems with the zoom functionality for images on canvas within Angular

Encountering a challenge with zooming in and out of an image displayed on canvas. The goal is to enable users to draw rectangles on the image, which is currently functioning well. However, implementing zoom functionality has presented the following issue: ...

Incorporating a dynamic HTML editing button to every new row in a table using JavaScript

My application features a form that allows users to dynamically add new rows to a table using JavaScript: // Function to add a new account row if (tit.innerHTML === "Add Account"){ var table = document.getElementById(tableId); var row = table ...

Using JavaScript, import the variable module object from a specific module

Is there a way to import a module object from a module if I am unsure of the specific objects I will need beforehand? How can I utilize a variable in place of fixed module names? import { dynamicVariable } from './module' The variable represents ...

Exploring the possibilities with JavaScript options

I am currently working on a project that involves a dropdown list... to complete unfinished sentences. Unfortunately, I am facing an issue with a message stating Uncaught TypeError: Cannot read property 'options' of null Below is a portion of m ...

What is the best way to execute NPM commands within the terminal of Visual Studio Code?

I recently installed npm in VSCode from extensions, but I am having trouble activating it. When I try to run the command 'npm init' in the terminal, I receive the following error message: "The term 'npm' is not recognized as the name of ...

Integrating React with the math.js library for enhanced functionality

My React component is having trouble integrating with the math.js library. When I attempt to display the output of the code in the console, everything works fine without resetting the state. However, when I try to use the result of the evaluate() function ...

Troubleshooting: Issues with jQuery Dropdown Menu

I'm currently working on a website that includes a settings feature with a button. My goal is to have the options and other links display in a dropdown menu when hovered over. Although I have written what I believe to be the correct code, it's no ...

Retrieving numerical values from strings using JavaScript

The text I have is formatted as follows: let str = "url(#123456)"; Within the given string, there is a number embedded in it. This number could appear anywhere in the string. I am looking to extract the number 123456 from the provided text. My current ...

Adding a Font Awesome icon on the fly in Vue.js

In my Vue modal, I have two inputs along with a button that adds two more inputs dynamically when clicked. Everything is functional, but I want to include a font awesome icon next to the dynamically created inputs. How can I achieve this in Vue? Here' ...