Tips for maintaining the integrity of an Array when passing it as an argument to a function in Javascript

I am working with an Array of objects called A

There are 2 different drawing functions that make changes to A in their own unique ways. I want to preserve the original state of A. Are there best practices for achieving this? My current approach feels a bit unnatural:

var A;//Should always remain unchanged

drawGraphX(A){
//Make modifications to A for drawing purposes, but I want to retain the original A
B=JSON.parse(JSON.stringify(A));
//Perform operations on B instead
}

drawGraphY(A){
//Adjustments made to A for drawing
B=JSON.parse(JSON.stringify(A));
//Operations carried out using B
}

Answer №1

It seems that the key to solving this issue is to avoid modifying the data within your function altogether!

Let's consider a scenario where A represents an array of x/y points intended for a chart.

var A = [{x:1,y:1},{x:2,y:2},{x:3,y:3}];

If your function only requires the x values, are you implementing it like this:

function drawGraphX(A){
   for(var i=0;i<A.length;i++)
      A[i] = A[i].x; 

   // graph drawing process follows
}

In the above instance, indeed, you are altering the original content of A by passing its reference to the function and updating the elements directly. This practice should be avoided, and instead, you should opt for the following approach:

function drawGraphX(A){
   var data = A.map(function(e){
       return e.x;
   });

   // 'data' now contains solely the x values in an array
}

Answer №2

If you want to make a shallow copy of an array, consider using drawGraphX(A.slice()). This method will create a new copy of the array but keep in mind that it won't clone objects within the array.

var A = [{test:'foo', test2:'bar'}, {test:'foo1', test2:'bar1'}];
var B = A.slice();
A[0].test = 'foobar';
console.log(B[0].test);

In this case, "foobar" will be returned because the object inside the array is not cloned. So, mutating the array itself is fine, but not its elements (the same applies to Array.from(A)).

Answer №3

To simplify the process, you can utilize the Array.from() method to create a new array for your function. Instead of calling drawGraphX(A), try calling drawGraphX(Array.from(A)). This will generate a fresh array with the same data as 'A', making it quick and easy.

var b = Array.from(A);
drawGraphX(b);

Alternatively, you can directly use:

drawGraphX(Array.from(A));

It's important to note that creating a new array using this method maintains references to the original objects. Therefore, modifying the new array won't affect the source array, but altering any shared objects will impact the original data. For example:

var a = [1, 2];
var b = Array.from(a);
b[0] = b[0]++;
console.log(a); // outputs [2, 2];

However,

b.push[3];
console.log(a); // displays [1, 2]
console.log(b); // shows [1, 2, 3];

You can test this concept with the following link: https://jsfiddle.net/5hLjajc0/1/

Answer №4

A more refined solution would involve using a switch statement that checks if an object is undefined, then takes the parent's value:

function switchObjects(obj, parent){
 return function(keys, value){
  keys = keys.split(".");
  var element = obj;
  var parentElement;
  for(var key of keys){
    parentElement = element;
    element = element[key];        
  }
  if(element === undefined){
          var element = parent;
          var parentElement;
          for(var key of keys){
           parentElement = element;
           element = element[key];        
           }
   }
  if(value){
    parentElement[keys[keys.length]] = value;
  }
  return element;
  };}

Usage example:

parent = [0, 1, 3]; //unchangeable
obj = [, 5, ];
callFunction(switchObjects(obj, parent));
function callFunction(el){
//read
el("0"); //0
el("1"); //5
el("2"); //3
//write
el("0", 12); //do not override parent
//also works with multidimensional objects:
el("0.a");
}

This approach represents an enhanced version of prototypes:

var obj={
 0:function(){
  alert("original prototype");
 },
 1:5
 }

 callFunction(Object.create(obj));//...
 callFunction(Object.create(obj));//...

With this method, you can access the properties of prototypes that cannot be easily overridden:

function callFunction(arg){
  arg[0](); //works as expected
  arg[0] = function(){
    alert("hi");
  }
  arg[0](); //hi
  }

This extension does not overwrite the prototype; it extends the argument. To override, you can still do:

arg.prototype[0] = function(){
 alert("hi prototype");
};

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

Disabling other fields with Bootstrap DateTimePicker

I am interested in understanding how the Bootstrap DateTimePicker stores dates. I need to disable other text box fields on my webpage based on this information. I have set up a page with multiple GridViews for querying purposes and I want to prevent users ...

Tips for refreshing the Vuex store to accommodate a new message within a messageSet

I've been working on integrating vue-socket.io into a chat application. I managed to set up the socket for creating rooms, but now I'm facing the challenge of displaying messages between chats and updating the Vuex store to show messages as I swi ...

Building a web proxy with node.js and express

I'm currently in the process of designing a personalized web proxy using JavaScript to allow users to surf the internet through a designated website, similar to this . One challenge I encountered is transferring the response from a URL back to the us ...

Retrieve a file from a remote server without storing it locally on the server

I need to download a zip file from another server without saving it locally. Currently, I am sending a POST request to the server which responds with the zip file, then I save it on my local server and send it using res.download. What I would like is to di ...

Enhancing functionality with jQuery: updating multiple input fields at

Currently, I am attempting to utilize jQuery to modify some HTML text by adjusting a slider. I have managed to accomplish this; however, I also need it to happen only if a checkbox is checked. How can I integrate both conditions and ensure that the text ch ...

How to incorporate template literals when sending JSON responses in Node.js?

Utilizing express and aiming to return some JSON, I am considering using a template literal. Here is my current approach: resp.status(201).json({ message: "Customer added to database", url: "http://localhost:5000/Customer/" + doc._id ...

Incorporating SVG line elements into a line graph

After successfully creating an interactive line chart using nvd3, I am now looking to enhance it by adding an svg line to represent a baseline. Within my function that constructs and displays the line chart, I have the following code: function _buildGrap ...

What distinguishes passing an event handler directly versus encapsulating it within an arrow function in React?

Are there any distinctions in how these 2 inputs utilize the event handler in terms of functionality or performance? export default function App() { const handleChange = e => { console.log(e.target.value); } return ( <div className=& ...

add element into the center of the div

I am attempting to insert an element (such as a div) in the middle of another div and directly after two line breaks. Below is an example of my code. The length of the div may vary. <html> <head> <title></title> <script ...

What steps can be taken to enhance the functionality of this?

Exploring ways to enhance the functionality of JavaScript using the underscore library. Any ideas on how to elevate this code from imperative to more functional programming? In the provided array, the first value in each pair represents a "bucket" and the ...

Guide on incorporating jQuery into a jQuery plugin within an Angular 2+ application using Webpack or Angular CLI

I'm running into an issue importing a jQuery plugin into a single Angular component. It works fine in most browsers, but IE 11 is giving me this error: SCRIPT1002: Syntax error main.bundle.js (1376,1) When I investigate the error, it points me to th ...

How can we prevent excessive hook calls when utilizing components in React?

I've run into an issue with the modal component hook I created below. I want to set up this modal at the app level so that I can easily access it via a global state like Zustand whenever necessary. Here is the structure of the modal component: Crea ...

Increase the visibility of a div using Jquery and decrease its visibility with the "

Can anyone assist me with implementing a "show more" and "show less" feature for a specific div? I have put together a DEMO on codepen.io In the DEMO, there are 8 red-framed div elements. I am looking to display a "show more" link if the total number of ...

What is the process for refreshing Textures in ThreeJs?

How can I refresh my skybox textures by selecting thumbnails? You can check out this example for reference: canvas_geometry_panorama.html Each thumbnail title corresponds to a folder that contains the skybox images. By using a simple jQuery script, a ...

Is it possible that the JSON is formatted correctly but there is an issue with parsing it in JavaScript?

const plantDisease={ "apple_scab": { "symptoms": "Leaves covered in a dark velvet layer, showing velvety olive-green to black spots", "cause": "Venturia inaequalis", "natural_control": "Utilize resistant varieties like Prima, Priscilla, Sir P ...

Oops! Looks like there was a glitch in the server for the application. The page you are looking for cannot be found. Error code: HTTP 404. Requested URL: /

Description: Oops! The page you are trying to access cannot be found. It may have been removed, renamed, or is currently unavailable. Please double-check the URL for any errors. Requested URL: /UsersPage/undefined I've got this AJAX script that is s ...

Converting an object of objects into an associative array using Javascript and JSON

Using AngularJS, I am sending this data to my API : $http.post('/api/test', { credits: { value:"100", action:"test" } }); Upon receiving the data in my nodeJS (+Express) backend, it appears as follows : https://i.stack.imgur.com/NurHp.png Why ...

How can AngularJS ng-repeat be used to extract HTML elements?

I need help parsing HTML that is received from the server as a string. Here is an example of what I receive: <img src="http://gravatar.com/avatar/9a52267d32ad2aaa4a8c2c45b83396e5?d=mm&amp;s=&amp;r=G" class=" user-1-avatar avatar- photo" width=" ...

JavaScript Magic: Hide Div when Clicking Away

I need a solution where clicking outside of the My DIV with the ID Container_ID will hide all elements within the Container by setting their style to display: none;. Currently, the JavaScript code I am using partially achieves this functionality, but it al ...

How to automatically disable a button in reactjs when the input field is blank

I have a component called Dynamic Form that includes input fields. The challenge I am facing is how to disable the submit button when these input fields are empty, although the validateResult function fails to return false. import cn from "classname ...