问题
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