AngularJS : copy vs extend

99封情书 提交于 2019-12-30 10:10:09

问题


Explanation :

we come across some situation in which we need to copy one object to another object. In that case, we probably have two solutions: angular.copy() or angular.extend().

Challenge i am facing :

As we know angular.copy(source, destination) creates a deep copy of source object and assign it to destination. By writing deep copy, we mean that a new copy of the referred object is made and its working fine.

deep copy code :

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

Here, I modify the source object mySource.name = "Jindal" but it is not affecting the destination object myDest as expected. If we check mySource.obj === myDest.obj, this will give false because both point to different objects.

Now,I am facing issue with angular.extend(destination, source) as it creates a shallow copy means in this both source and destination will point to same address. So, if i will modify source object then it will also reflect in destination object. But it's not happening.

shallow copy code :

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

jsfiddle : https://jsfiddle.net/U3pVM/24322/

As i am new in this, need help to understand the proper flow of angular.copy() & angular.extend().

Any immediate help will be highly appreciable. Thanks


回答1:


I updated the code . Now angular.extends works as you expected. Remember that if you pass angular.extends an empty object as first parameter (destination) and then the source, angular is going to preserve both objects and copy only the properties, just like angular.copy does.

// angular.copy()

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

mySource.name = "Rohit";
console.log(mySource); // Object {name: "Rohit", 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 = "Rohit";
console.log(mySource); // Object {name: "Rohit", age: "24", obj: Object}
console.log(myDest); // Object {name: "Rohit", age: "24", obj: Object}
console.log(mySource.obj === myDest.obj); // True



回答2:


agular.copy clones (deep copy) an object and creates a new object using the same values, while angular.extend does a shallow copy so that the attributes refer to same values in memory. A very nice explanation is given here which differentiates very well between .copy(), .extend() and .merge() methods




回答3:


Primitives are copied by value instead of by reference but first try to understand copy vs extend

copy

Iterates each property of an object, if it's a primitive just copy it, if it's an object create a new object and perform a recursive copy

The implementation may looks as follows, note that obviously there are some additional cases but I'm keeping it simple

function copy(dest, source) {
  for (var property in source) {
    if (typeof source[property] === 'object') {
      var clone = {}
      copy(clone, source[property])
      dest[property] = clone
    } else {
      // a primitive
      dest[property] = source[property]
    }
  }
}

extend

Iterates each property of an object, if it's a primitive just copy it, if it's an object create a reference to the object instead of creating a new object which has the same references as the original object

function extend(dest, source) {
  for (var property in source) {
    dest[property] = source[property]
  }
}

Perhaps you're expecting that when you do a shallow copy primitives will also be shallow copied however as you see above they're always cloned, to solve your problem you should instead change properties of a referenced object (achieved with a shallow copy)

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



回答4:


For the copy of the object the following things metters.

  • Object points to same memory location or not

    • Normal copy - Yes
    • Angular copy - No
    • Angular extend - No
    • Angular merge - No
  • Inner object points to the same memory location or not

    • Normal copy - Yes
    • Angular copy - No
    • Angular extend - No
    • Angular merge - No
  • Does copy keep the current child objects or remove that objects

    • Normal copy - Override
    • Angular copy - Override
    • Angular extend - Keep
    • Angular merge - Keep

Here is the plunker copy for that

// '=' 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 = "Rohit";
console.log(mySource); // Object {name: "Rohit", 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 = "Rohit";
console.log(mySource); // Object {name: "Rohit", age: "24", obj: Object}
console.log(myDest); // Object {name: "sakshi", age: "24", obj: Object}
console.log(mySource === myDest); // false //points to different object
console.log(mySource.obj === myDest.obj); // false //points to different object

// angular.extend()
console.info('angular extend');
var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = {oldObj:'old'}
angular.extend(myDest,mySource);
mySource.name = "Rohit";
console.log(mySource); // Object {name: "Rohit", age: "24", obj: Object}
console.log(myDest); // Object {oldObj:'old',name: "sakshi", age: "24", obj: Object}
mySource.obj.key = '123';
console.log(myDest.obj.key);
console.log(mySource === myDest); // false //points to different object
console.log(mySource.obj === myDest.obj); // True //points to same object

// angular.extend()
console.info('angular merge');
var mySource = {'name' : 'sakshi', 'age' : '24', 'obj' :{'key':'value'}}
var myDest = {oldObj:'old'}
angular.merge(myDest,mySource);
mySource.name = "Rohit";
console.log(mySource); // Object {name: "Rohit", age: "24", obj: Object}
console.log(myDest); // Object {oldObj:'old',name: "sakshi", age: "24", obj: Object}
console.log(mySource === myDest); // false //points to different object
console.log(mySource.obj === myDest.obj); // false //points to different object


来源:https://stackoverflow.com/questions/36827866/angularjs-copy-vs-extend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!