jquery 扩展与角度扩展
Posted
技术标签:
【中文标题】jquery 扩展与角度扩展【英文标题】:jquery extend vs angular extend 【发布时间】:2013-05-23 18:07:49 【问题描述】:这两个扩展函数有什么区别?
angular.extend(a,b);
$.extend(a,b);
虽然 jquery.extend 有据可查,但 angular.extend 缺少详细信息,并且那里的 cmets 没有提供任何答案。 (https://docs.angularjs.org/api/ng/function/angular.extend)。
angular.extend 也提供深拷贝吗?
【问题讨论】:
上面写着by copying all of the properties
,我假设all
这个词的意思是everything
,在JS世界里是deep copy
的同义词。
@Ohgodwhy:我非常怀疑这是一个 deep 副本。如果一个属性(比如,p
)引用了一个对象,我会和你打赌,在调用之后,src.p
和 dst.p
都引用了 same 对象。
误导性的角度文档是。
【参考方案1】:
angular.extend
和jQuery.extend
非常相似。它们都从一个或多个源对象到目标对象执行 shallow 属性复制。比如:
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
引用 same 对象(不是对象的副本)。
它们都返回目标对象。
它们都支持多个源对象。
它们都按顺序执行多个源对象,因此如果多个源对象具有相同的属性名称,则最后一个源对象将“获胜”。
测试页面:Live Copy | Live Source
<!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>
【讨论】:
另外值得一提的是,jQuery 允许您将布尔值true
指定为第一个参数,以便进行深层复制。见这里:api.jquery.com/jQuery.extend/…
一个主要区别:extend 仅在存在同名属性时复制值,copy 是复制整个对象,因此如果在 $scope 变量上使用它,则会丢失数据绑定!就像 asafge 的回答所说的那样。
angular.extend()
不会为您复制 getter 和 setter。见github.com/angular/angular.js/issues/8573
@demisx:jQuery 也没有。他们都复制了属性的 value,我可能认为这是正确的行为。【参考方案2】:
两者之间有一个细微的区别,之前的答案中没有提到。
jQuery 的 .extend() 允许您有条件地添加键、值对,前提是值已定义。所以在 jQuery 中,如果 x
未定义,$.extend(, 'a': x ? x : undefined);
将返回 。
然而,在 Angular 的 .extend() 中,angular.extend(, 'a': x ? x : undefined);
将返回 'a': undefined
,即使 x
未定义。所以无论如何,钥匙都会在那里。
这可能是好事也可能是坏事,这取决于您的需要。无论如何,这是两个库之间行为的差异。
【讨论】:
我也遇到了同样的问题。相关示例:plnkr.co/edit/2ca7AfIhgolmwaNaYvY4?p=preview 如果您希望两个函数的行为相同,这绝对是一件坏事。 2014 年甚至有一个拉取请求来解决这个问题,但没有实现:github.com/angular/angular.js/pull/8387【参考方案3】:1.0.7 angularjs 版本声明扩展和复制方法不再复制 angularjs 内部 $$hashKey 值。
查看发行说明@https://github.com/angular/angular.js/blob/master/CHANGELOG.md
angular.copy/angular.extend:不要在复制/扩展函数中复制 $$hashKey。 (6d0b325f, #1875)
在 Chomre 开发工具方法中对 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 另一方面做一个浅拷贝。
【讨论】:
“在 Chomre 开发工具方法中对 angular.copy 的快速测试表明它确实进行了深层复制。” 不,它没有。extend
没有,反正我没看copy
。
啊,copy
有,extend
没有:jsbin.com/eketan/2 但问题是关于extend
,而不是copy
。
是的 - 当我发帖时,您已经非常彻底地回答了扩展问题。我想确保复制方法也得到评估,因为它可以为他们试图完成的事情提供解决方案。
感谢你们两位如此彻底地澄清这件事:)【参考方案4】:
AngularJS 中的 .extend() 的工作方式类似于 jQuery 的 .extend()
http://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);
【讨论】:
以上是关于jquery 扩展与角度扩展的主要内容,如果未能解决你的问题,请参考以下文章