Is there any difference in behavior between the angularjs angular.extend(src, dst) and the javascript Object.assign(src, dst) functions?
Using the test from , they both seem identical.
If they really are, is there any difference in performance? What are pros and cons for using one over the other?
2 Answers
Looking at the source of angular.extend (baseExtend actually, angular.extend is a few lines below it and uses baseExtend), it's simply a shallow copy. The one exception is that it copies a $$hashKey property, which is used by AngularJS to do object tracking.
I would suggest using Object.assign for code that's not AngularJS-specific, while using angular.extend if you're dealing with objects used by AngularJS controllers (such as scope variables).
For starters, angular.extend has an option to do a "deep" clone, so there is that...
If performance is truly a consideration for you then, yes, angular.extend is definitely a "slower" process, but really that shouldn't matter unless you are calling this on large data sets.
Bottom line, angular.extend is there for three reasons. 1) a replacement for Object.assign in the case of old browsers, 2) a way to do a "deep" copy, 3) ensure that an angular-managed object doesn't break if used as the target of an assign call. That is to say, its $$hashKey property does not get overridden.
If you're really curious, have a look at the source code :-)
function baseExtend(dst, objs, deep) {
var h = dst.$$hashKey;
for (var i = 0, ii = objs.length; i < ii; ++i) {
var obj = objs[i];
if (!isObject(obj) && !isFunction(obj)) continue;
var keys = Object.keys(obj);
for (var j = 0, jj = keys.length; j < jj; j++) {
var key = keys[j];
var src = obj[key];
if (deep && isObject(src)) {
if (isDate(src)) {
dst[key] = new Date(src.valueOf());
} else if (isRegExp(src)) {
dst[key] = new RegExp(src);
} else if (src.nodeName) {
dst[key] = src.cloneNode(true);
} else if (isElement(src)) {
dst[key] = src.clone();
} else {
if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
baseExtend(dst[key], [src], true);
}
} else {
dst[key] = src;
}
}
}
setHashKey(dst, h);
return dst;
}