这两个扩展函数之间有什么区别?
angular.extend(a,b);
$.extend(a,b);
尽管jquery.extend有很好的文档记录,但angular.extend缺乏细节,那里的评论没有提供答案。(https://docs.angularjs.org/api/ng/function/angular.extend).
angular.extend是否也提供深拷贝?
这两个扩展函数之间有什么区别?
angular.extend(a,b);
$.extend(a,b);
尽管jquery.extend有很好的文档记录,但angular.extend缺乏细节,那里的评论没有提供答案。(https://docs.angularjs.org/api/ng/function/angular.extend).
angular.extend是否也提供深拷贝?
angular.extend
和 jQuery.extend
非常相似。它们都会将一个或多个源对象的属性进行浅拷贝,然后将其赋值到目标对象上。例如:
var src = {foo: "bar", baz: {}};
var dst = {};
whatever.extend(dst, src);
console.log(dst.foo); // "bar"
console.log(dst.baz === src.baz); // "true", it's a shallow copy, both
// point to same object
angular.copy
提供了一个深度复制:
var src = {foo: "bar", baz: {}};
var dst = angular.copy(src);
console.log(dst.baz === src.baz); // "false", it's a deep copy, they point
// to different objects.
回到extend
:我只看到一个显著的区别,那就是jQuery的extend
允许您仅指定一个对象,在这种情况下,jQuery
本身是目标。
共同点:
它是浅复制。因此,如果src
具有引用对象的属性p
,则dst
将获得一个引用同一对象(而不是对象的副本)的属性p
。
它们都返回目标对象。
它们都支持多个源对象。
它们都按顺序处理多个源对象,因此在多个源对象具有相同的属性名称的情况下,最后一个源对象将“获胜”。
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<meta charset=utf-8 />
<title>Extend!</title>
</head>
<body>
<script>
(function() {
"use strict";
var src1, src2, dst, rv;
src1 = {
a: "I'm a in src1",
b: {name: "I'm the name property in b"},
c: "I'm c in src1"
};
src2 = {
c: "I'm c in src2"
};
// Shallow copy test
dst = {};
angular.extend(dst, src1);
display("angular shallow copy? " + (dst.b === src1.b));
dst = {};
jQuery.extend(dst, src1);
display("jQuery shallow copy? " + (dst.b === src1.b));
$("<hr>").appendTo(document.body);
// Return value test
dst = {};
rv = angular.extend(dst, src1);
display("angular returns dst? " + (rv === dst));
dst = {};
rv = jQuery.extend(dst, src1);
display("jQuery returns dst? " + (rv === dst));
$("<hr>").appendTo(document.body);
// Multiple source test
dst = {};
rv = angular.extend(dst, src1, src2);
display("angular does multiple in order? " +
(dst.c === src2.c));
dst = {};
rv = jQuery.extend(dst, src1, src2);
display("jQuery does multiple in order? " +
(dst.c === src2.c));
function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}
})();
</script>
</body>
</html>
true
作为第一个参数来指定进行深度复制。请参见此处:http://api.jquery.com/jQuery.extend/#jQuery-extend-deep-target-object1-objectN - treefaceangular.extend()
不会为您复制getter和setter。请查看https://github.com/angular/angular.js/issues/8573。 - demisx这两种方法之间有一个微妙的区别,之前的回答中没有提到。
jQuery的.extend()允许在值被定义时有条件地添加键值对。因此,在jQuery中,这个语句:$.extend({}, {'a': x ? x : undefined});
如果x
未定义,则返回{}
。
然而,在Angular的.extend()中,这个语句:angular.extend({}, {'a': x ? x : undefined});
即使x
未定义,也会返回{'a': undefined}
。所以,无论如何,这个键都会存在。
这可能是好事或坏事,具体取决于您的需要。无论如何,这是两个库之间行为上的差异。
1.0.7版的angularjs构建说明,扩展和复制方法不再复制angularjs内部的$$hashKey值。
请参见发布说明@https://github.com/angular/angular.js/blob/master/CHANGELOG.md
angular.copy/angular.extend:在复制/扩展函数中不复制$$hashKey。(6d0b325f,#1875)
通过Chrome开发工具的angular.copy快速测试方法显示它确实进行了深度复制。
x = {p: 3, y: {x: 5}}
Object {p: 3, y: Object}
x
Object {p: 3, y: Object}
z = angular.copy(x);
Object {p: 3, y: Object}
z
Object {p: 3, y: Object}
x
Object {p: 3, y: Object}
z.y.x = 1000
1000
x
Object {p: 3, y: Object}
p: 3
y: Object
x: 5
__proto__: Object
__proto__: Object
z
Object {p: 3, y: Object}
p: 3
y: Object
x: 1000
__proto__: Object
__proto__: Object
相比之下,angular.extend只进行浅拷贝。
extend
也不是,反正我没看过 copy
。 - T.J. Crowdercopy
可以,extend
不行:http://jsbin.com/eketan/2 但问题是关于extend
而不是copy
。 - T.J. Crowderhttp://jsfiddle.net/Troop4Christ/sR3Nj/
var o1 = {
a: 1,
b: 2,
c: {
d:3,
e:4
}
},
o2 = {
b: {
f:{
g:5
}
}
};
console.log(angular.extend({}, o1, o2));
console.log(o1);
console.log(o2);
p
)引用了一个对象,我敢打赌,在调用之后,src.p
和dst.p
两者都会引用同一个对象。 - T.J. Crowder