2016-04-24 28 views
2

说明:AngularJS:复制VS延长

我们遇到一些情况,我们需要一个对象复制到另一个对象。在这种情况下,我们可能有两种解决方案:angular.copy()angular.extend()

挑战我面临着:

我们知道angular.copy(source, destination)创建源对象的深层副本,并将其分配到目的地。通过书写深层复制,我们的意思是创建一个新的引用对象的副本,它的工作正常。

深拷贝代码:

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 

在这里,我修改源对象mySource.name = "Jindal"但它不影响预期目标对象myDest。 如果我们检查mySource.obj === myDest.obj,这会给出错误,因为两者都指向不同的对象。

现在,我面临与angular.extend(destination, source)问题,因为它创建shallow copy意味着在这个源和目的地将指向相同的地址。 So, if i will modify source object then it will also reflect in destination object. But it's not happening.

浅拷贝代码:

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/

正如我在我新的,需要帮助了解angular.copy()& angular.extend的正常流动( )。

任何即时帮助将非常可观。谢谢

回答

8

我更新了the code。现在angular.extends按照您的预期工作。请记住,如果传递angular.extends一个空对象作为第一个参数(目的地),然后是源,angular将保留这两个对象并仅复制属性,就像angular.copy一样。

// 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

谢谢..良好的解释! –

2

agular.copy克隆(深层副本)的对象,并创建使用相同的值的新对象,而angular.extend确实浅表副本,使得属性指相同的值在存储器中。一个很漂亮的给出解释here其区别.copy().extend().merge()非常好之间的方法

2

原语是按值而不是按引用,但先了解复制copy VS extend

副本

迭代一个对象的每个属性,如果它是一个原始的只是复制它,如果它是一个对象创建一个新的对象并执行递归复制

实现可能看起来如下,请注意,显然有一些额外的情况,但我保持简单

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] 
    } 
    } 
} 

延长

迭代一个对象的每个属性,如果它是一个原始的公正复制它,如果它是一个对象创建的对象的引用而不是创建具有与原始对象

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

也许你会expectin同样引用了一个新对象g当你做一个浅拷贝时,基元也会被浅拷贝,但是如你所见,它们总是被克隆,为了解决你的问题,你应该改变一个被引用对象的属性(用浅拷贝来实现)

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

对于这个对象的副本,下面的东西是变化的。

  • 对象指向同一个内存位置或不

    • 普通副本 - 是
    • 角副本 - 无
    • 角范围 - 无
    • 角合并 - 无
  • 内部对象指向同一个内存位置或不

    • 普通副本 - 是
    • 角副本 - 无
    • 角范围 - 无
    • 角合并 - 无
  • 是否保留当前子对象或删除该对象

    • 普通副本 - 覆盖
    • 角拷贝 - 覆盖
    • 角范围 - 保持
    • 角合并 - 保持

这里是plunker副本为

// '=' 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

您的代码显示了一件事('angular.extend'对内部对象使用相同的引用),并且您的摘要指出了另一件事。 – greenoldman

+0

是的。我认为angular.extend在'Inner object指向相同的内存位置或不是'列表中应该是'是'。 –