web-dev-qa-db-fra.com

jquery extend vs angular extend

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?

62
Renaud

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>
96
T.J. Crowder

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.

31
asafge

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.

6
Mike Pugh

.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);
1
RavenHursT