Quelle est la différence entre ces deux fonctions d'extension?
angular.extend(a,b);
$.extend(a,b);
Bien que le jquery.extend soit bien documenté, le angular.extend manque de détails et les commentaires ne fournissent aucune réponse. ( https://docs.angularjs.org/api/ng/function/angular.extend ).
Est-ce que angular.extend fournit également une copie complète?
angular.extend
et jQuery.extend
sont très très similaires. Ils font tous deux une copie de propriété shallow d'un ou plusieurs objets source vers un objet de destination. Ainsi, par exemple:
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
fournit une copie profonde :
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.
Revenir à extend
: Je ne vois qu'une différence significative, c'est que extend
de jQuery vous permet de spécifier un seul objet, auquel cas jQuery
lui-même est la cible.
Choses en commun:
C'est une copie superficielle. Donc, si src
a une propriété p
qui fait référence à un objet, dst
obtiendra une propriété p
qui fait référence à pareil objet (pas une copie de l'objet).
Ils renvoient tous les deux l'objet de destination.
Ils prennent tous les deux en charge plusieurs objets source.
Ils font tous deux les multiples objets source dans l'ordre, et donc le dernier objet source "gagnera" au cas où plus d'un objet source aurait le même nom de propriété.
Page de test: Live Copy | Source en direct
<!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>
Il y a une différence subtile entre les deux qui n'était pas mentionnée dans les réponses précédentes.
.extend () de jQuery vous permet de conditionnellement ajouter clé, paires de valeurs, uniquement si la valeur est définie. Ainsi, dans jQuery, ceci: $.extend({}, {'a': x ? x : undefined});
renverra {}
Dans le cas où x
n'est pas défini.
Cependant, dans .extend () d'Angular, ceci: angular.extend({}, {'a': x ? x : undefined});
renverra {'a': undefined}
, Même si x
n'est pas défini. La clé sera donc là, quoi qu'il arrive.
Cela peut être une bonne ou une mauvaise chose, selon vos besoins. Quoi qu'il en soit, c'est une différence de comportement entre les deux bibliothèques.
La version 1.0.7 angularjs indique que les méthodes extend & copy ne copient plus les valeurs $$ hashKey internes angularjs.
Voir les notes de version @ https://github.com/angular/angular.js/blob/master/CHANGELOG.md
angular.copy/angular.extend: ne copiez pas $$ hashKey dans les fonctions copier/étendre. (6d0b325f, n ° 1875)
Un test rapide de la méthode angular.copy dans les outils de développement Chomre montre qu'elle effectue une copie complète.
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 d'autre part fait une copie superficielle.
.extend () dans AngularJS fonctionne de manière similaire au .extend () de jQuery
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);