2016-04-24 72 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指向相同的內存位置或不是'列表中應該是'是'。 –