AngularJS: comparing the differences between copying and extending

Explaining Different Object Copy Methods :

When it comes to copying objects in certain situations, two common solutions are often considered: using angular.copy() or angular.extend().

Challenge I Am Currently Facing :

The

angular.copy(source, destination)
method creates a deep copy of the source object and assigns it to the destination. This means that modifications made to the source object do not affect the destination object.

Code for Deep Copy :

var mySource = {'name' : 'Beta', 'age' : '24'}
var myDest = {}
angular.copy(mySource,myDest);
mySource.name = "Alpha";
console.log(mySource); // Object {name: "Alpha", age: "24"}
console.log(myDest); // Object {name: "Beta", age: "24"}
console.log(mySource.obj === myDest.obj); // false

However, with

angular.extend(destination, source)
, a shallow copy is created where both source and destination point to the same address. Therefore, modifying the source will also reflect in the destination object, contrary to what might be expected.

Code for Shallow Copy :

var mySource = {'name' : 'Beta', 'age' : '24'}
var myDest = {}
angular.extend(myDest,mySource);
mySource.name = "Alpha";
console.log(mySource); // Object {name: "Alpha", age: "24"}
console.log(myDest); // Object {name: "Beta", age: "24"}
console.log(mySource.obj === myDest.obj); // True

For further reference, you can view this jsfiddle link: https://jsfiddle.net/U3pVM/24322/

If anyone could provide insight on the proper usage of angular.copy() & angular.extend(), it would be greatly appreciated as I am new to these concepts. Thank you.

Answer №1

I made some updates to the code. Now, the angular.extends function is functioning as expected. It's important to note that when you provide an empty object as the first parameter (destination) in angular.extends and then add the source, Angular will keep both objects intact and only copy over the properties, much like angular.copy does.

// angular.copy()

var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = angular.copy(mySource);

mySource.name = "Beta";
console.log(mySource); // Object {name: "Beta", age: "24", obj: Object}
console.log(myDest); // Object {name: "sakshi", age: "24", obj: Object}
console.log(mySource.obj === myDest.obj); // false

// angular.extend()

var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = angular.extend(mySource);
mySource.name = "Beta";
console.log(mySource); // Object {name: "Beta", age: "24", obj: Object}
console.log(myDest); // Object {name: "Beta", age: "24", obj: Object}
console.log(mySource.obj === myDest.obj); // True

Answer №2

agular.copy is a method that creates a deep copy of an object, meaning it generates a new object with the same values. On the other hand, angular.extend only performs a shallow copy, so the attributes point to the same values in memory. If you want a detailed explanation about the differences between .copy(), .extend(), and .merge() methods, check out this resource.

Answer №3

Understanding the concept of copying versus extending is important when dealing with primitives in JavaScript.

Copying:

When copying, each property of an object is iterated through. If the property is a primitive value, it is simply copied. If it is an object, a new object is created and a recursive copy is performed.

The following is a basic implementation of the copy function:

function copy(destination, source) {
  for (var prop in source) {
    if (typeof source[prop] === 'object') {
      var clone = {};
      copy(clone, source[prop]);
      destination[prop] = clone;
    } else {
      // copy the primitive
      destination[prop] = source[prop];
    }
  }
}

Extending:

Extending also iterates through each property of an object. If the property is a primitive value, it is copied. If it is an object, a reference to the original object is created instead of creating a new one.

function extend(destination, source) {
  for (var prop in source) {
    destination[prop] = source[prop];
  }
}

It's important to note that when performing a shallow copy, primitives are always cloned. To avoid this, you can change properties of a referenced object achieved through a shallow copy.

var mySource = {person: {'name' : 'Beta', 'age' : '24'}}
var myDest = {}
extend(myDest,mySource);
mySource.person.name = "Alpha";
console.log(mySource); // Output: Object {person: {name: "Alpha", age: "24"}}
console.log(myDest);  // Output: Object {person: {name: "Alpha", age: "24"}}
console.log(mySource.obj === myDest.obj); // Output: True

Answer №4

When dealing with object copies, certain factors come into play.

  • Check if the object points to the same memory location or not

  • Normal copy - Yes

  • Angular copy - No

  • Angular extend - No

  • Angular merge - No

  • Determine if inner objects point to the same memory location or not

  • Normal copy - Yes

  • Angular copy - No

  • Angular extend - No

  • Angular merge - No

  • Decide whether the copy retains current child objects or removes them

  • Normal copy - Override

  • Angular copy - Override

  • Angular extend - Keep

  • Angular merge - Keep

For a demonstration and examples, you can view this Plunker link.

// '=' assignment copy
console.info('assignment copy');
var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = {oldObj:'old'} //old properties will be override
myDest = mySource;
mySource.name = "Beta";
console.log(mySource); // Object {name: "Beta", age: "24", obj: Object}
console.log(myDest); // Object {name: "sakshi", age: "24", obj: Object}
console.log(mySource === myDest); // true         //points to same object
console.log(mySource.obj === myDest.obj); // true //points to same object

// angular.copy()
console.info('angular copy');
var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = {oldObj:'old'} //old properties will be override
angular.copy(mySource,myDest);
mySource.name = "Beta";
console.log(mySource); // Object {name: "Beta", age: "24", obj: Object}
console.log(myDest); // Object {name: &...

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

Ways to control the number of boxes that are checked

I am currently working on a script to restrict the number of checkboxes that can be checked, but I am encountering an issue where the script is disabling all checkboxes on the page. Is there a way to only disable a specific checkbox within a certain div? ...

Angular: Retrieving the Time Format from the Browser

Is there a way to retrieve the time format from the operating system or browser within Angular in order to display time in the user's preferred format? I have attempted to search for a solution, but have come up empty-handed. Thank you in advance! ...

Can you stop an image from being chosen on a website?

I have a website that features a table with text descriptions in the headers and question mark images (users can hover over them for help). Recently, I received a request to allow users to highlight and copy the table without including the images (using c ...

Issue with the dependency between THREE.ShaderPass and THREE.EffectComposer in Three.js

I am relatively new to three.js and trying to implement a bloom effect on my object using UnrealBloomPass.js through the effect composer function. However, I have encountered some errors related to THREE.ShaderPass in the Effect Composer that I am unable t ...

Defining variables within a jQuery function

Within my initialization function (init), I have defined some variables and an animation that utilizes those variables. The challenge arises when I want to use the same animation/variables in my clickSlide function. http://jsfiddle.net/lollero/4WfZa/ (Un ...

How can you refresh the source element?

Is there a way to make the browser reload a single element on the page (such as 'src' or 'div')? I have tried using this code: $("div#imgAppendHere").html("<img id=\"img\" src=\"/photos/" + recipe.id + ".png\" he ...

Exploring the intricacies of Node-Craigslist syntax

Greetings! I am currently utilizing the node-craigslist package found at https://github.com/brozeph/node-craigslist and I am in need of assistance with some syntax related to the details method. The documentation provides the following example: client . ...

Adding information to JSON array in AngularJS

I've encountered a challenging scenario where I need to transfer data from one controller to another. My application functions in the following way: View 1 -> retrieves users from a JSON array and displays them in a table. Upon clicking "add use ...

Creating interactive routes and pages using Next.js and Prisma, embracing dynamic functionality

I have product information cards stored in my database, and I successfully display them on the user's page. Now, I want to add a "More Details" button on each card that will link to a new page (/pages/card/[id]). However, I'm unsure how to retrie ...

React error: Unable to use 'in' operator to find 'length' in null

I am trying to access and filter a local array file, then store the filtered array as a state before passing it to a child component. // Sample array file const originalData = [ { "ComName":"A", "SDGs":"1", " ...

Issue with Bootstrap Modal content persists after refreshing the page

I created a modal with the following structure: <!-- Modal --> <div id="normale" class="modal fade" role="dialog"> <div class="modal-dialog" style="background-color:white"> <!-- Modal content--> <div class="modal-c ...

"Mastering the art of event delegation: A guide to effectively engaging with various

I have data that is generated dynamically, as shown in the snippet below: const resultsDiv = document.getElementById("results"); const getList = document.getElementById("example"); document.querySelector(".container").addEventListener("click", function ...

Creating a searchable and filterable singleSelect column in the MUI DataGrid: A step-by-step guide

After three days of working on this, I feel like I'm going in circles. My current task involves fetching data from two API sources (json files) using the useEffect hook and storing them in an array. This array contains a large number of products and a ...

The ngBindHtml directive is failing to display sanitized HTML content

I am encountering an issue with my Angular app where I am trying to insert HTML into the page using ngBindHtml, but it does not seem to be working. Take a look at my code below: <main id="main" ng-bind-html="oreGen | trust"></main> Here is my ...

Encountered an npm installation error in the console, with a post-installation error message indicating code

I implemented the postinstall command in my Node project with React, but I encountered numerous errors during the installation process in React. npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a8dbdcc9cac4cde ...

The basic function is ineffective when used within an if-condition

I am currently dealing with a JSON file that has some nesting: { "name": "1370", "children": [ { "name": "Position X", "value": -1 }, {...} ] "matches": [ { "certainty": 100, "match": { "name": "1370 ...

Click on ng-show to reveal more text in AngularJS

I am attempting to display an ellipsis for the content within a div, along with a '...more' text. Additionally, I am working on using ng-click to show the full text when '....more' is clicked. My goal is to add a hover class upon click ...

Decide whether to execute a promise or not, and then pass the resulting value to another promise

Struggling to find a way to write the following code without nested promises. function trickyFunction(queryOptions, data) { return new Promise((resolve, reject) => { if (data) { resolve(data); } else { // ... various conditions t ...

Exploring the GitHub Repository API with React

I am currently developing a feature that allows users to enter a username and view all the github repositories for that user in a separate react component within a repolist component. Although I can retrieve the JSON data for all the repos, I am facing is ...

One Background Image Serving Multiple Divs

Can you use one image (PNG or SVG) as the background for multiple divs? Take a look at the images below to see how it could work. And if the screen width gets smaller and the divs stack up vertically, is there a way to change the background accordingly? D ...