AngularJS : copy vs extend

后端 未结 4 1870
清歌不尽
清歌不尽 2021-01-13 23:27

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: ang

相关标签:
4条回答
  • 2021-01-13 23:56

    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

    0 讨论(0)
  • 2021-01-14 00:01

    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
    
    0 讨论(0)
  • 2021-01-14 00:08

    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
    
    0 讨论(0)
  • 2021-01-14 00:11

    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
    
    0 讨论(0)
提交回复
热议问题