228 votes

Quelle est la différence entre `new Object()` et la notation littérale d'objet ?

Quelle est la différence entre cette syntaxe basée sur les constructeurs pour créer un objet :

person = new Object()

...et cette syntaxe littérale :

person = {
    property1 : "Hello"
};

Il semble que les deux font la même chose, bien que JSLint préfère que vous utilisiez la notation littérale des objets.

Laquelle est la meilleure et pourquoi ?

7 votes

C'est pareil : a = new Object , a = new Object() , a = {} La version littérale est beaucoup plus simple et certains tests que j'ai effectués il y a quelque temps indiquent qu'elle est plus rapide, mais les compilateurs plus récents ont pu fausser mon affirmation. Il en va de même pour les tableaux littéraux

9 votes

Avec un peu de chance, vous déclarez vos variables avec la balise var dans votre code d'application pour éviter de polluer l'espace de noms global et de devoir chercher vos variables au-delà de l'enregistrement actuel dans la pile.

0 votes

@Samo hey mec, bon conseil. Mais qu'entendez-vous par "l'enregistrement actuel dans la pile" ? Si je rate quelque chose, j'aimerais l'apprendre.

251voto

Rémy DAVID Points 761

Il n'y a pas de différence pour un objet simple sans méthodes comme dans votre exemple. Cependant, il y a une grande différence lorsque vous commencez à ajouter des méthodes à votre objet.

Au sens propre :

function Obj( prop ) { 
    return { 
        p : prop, 
        sayHello : function(){ alert(this.p); }, 
    }; 
} 

Façon prototype :

function Obj( prop ) { 
    this.p = prop; 
} 
Obj.prototype.sayHello = function(){alert(this.p);}; 

Les deux méthodes permettent la création d'instances de Obj comme ça :

var foo = new Obj( "hello" ); 

Cependant, avec la méthode littérale, vous portez une copie de la sayHello dans chaque instance de vos objets. En revanche, avec la méthode du prototype, la méthode est définie dans le prototype de l'objet et partagée entre toutes les instances de l'objet. Si vous avez beaucoup d'objets ou beaucoup de méthodes, la méthode littérale peut entraîner un gaspillage de mémoire assez important.

56 votes

Pour moi, la question portait davantage sur les différences entre l'utilisation de l'Internet et l'utilisation de l'Internet. new Object() vs {} pour créer des objets vides.

0 votes

Et c'est ce que cela répond.

11 votes

@Lobabob A part la première phrase, cette réponse n'apporte aucune information sur la question de l'OP. Elle ne contient même pas de "new Object()`". Franchement, je pense que M. David a mal compris la question.

134voto

Kevin Points 57797

Ils font tous les deux la même chose (à moins que quelqu'un ait fait quelque chose d'inhabituel), à part que votre deuxième crée un objet y ajoute une propriété à celui-ci. Mais la notation littérale prend moins de place dans le code source. Ce qui se passe est clairement reconnaissable, donc l'utilisation de new Object() vous ne faites en réalité que taper davantage et (en théorie, si le moteur JavaScript ne l'optimise pas) faire un appel de fonction inutile.

Ces

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

ne font pas techniquement la même chose. La première crée simplement un objet. La seconde en crée un et lui attribue une propriété. Pour que la première soit la même, il faut alors une deuxième étape pour créer et attribuer la propriété.

Le "quelque chose d'inhabituel" que quelqu'un pourrait faire serait de suivre ou d'assigner au défaut Object mondial :

// Don't do this
Object = 23;

Dans ce très inhabituel cas, new Object échouera mais {} fonctionnera.

En pratique, il n'y a jamais de raison d'utiliser new Object plutôt que {} (sauf si vous avez fait cette chose très inhabituelle).

13 votes

L'auteur a choisi cette réponse comme étant correcte, mais elle est incomplète. Sachez qu'il existe des différences entre les deux syntaxes lorsque vous entrez dans l'allocation de mémoire.

2 votes

Il n'y a pas de différences. Si vous faites référence à l'une des réponses ci-dessous, elle est hors sujet, car elle parle du modèle d'objet basé sur des prototypes et de l'héritage (le code qui s'y trouve configure une classe Obj qui hérite d'un simple Object). Cette question ne porte pas sur la création d'une instance d'une classe personnalisée - elle porte sur la création d'une instance d'Object, et la réponse correcte à cette question est "il n'y a pas de différence".

0 votes

Pour info également () new Object() n'est pas nécessaire. ( en parlant du truc non requis)

59voto

James Wiseman Points 18347

En JavaScript, nous pouvons déclarer un nouvel objet vide de deux manières :

var obj1 = new Object();  
var obj2 = {};  

Je n'ai rien trouvé qui suggère qu'il existe une différence significative entre ces deux méthodes en ce qui concerne leur fonctionnement en coulisses (corrigez-moi si je me trompe - j'aimerais bien le savoir). Cependant, la seconde méthode (qui utilise la notation littérale d'objet) offre quelques avantages.

  1. Il est plus court (10 caractères pour être précis)
  2. Il est plus facile et plus structuré de créer des objets à la volée.
  3. Peu importe qu'un bouffon ait par inadvertance écrasé Object

Considérons un nouvel objet qui contient les membres Name et TelNo. En utilisant la convention new Object(), nous pouvons le créer comme suit :

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

El Expando Properties de JavaScript nous permet de créer de nouveaux membres de cette façon à la volée, et nous obtenons ce que nous voulions. Cependant, cette méthode n'est pas très structurée ou encapsulée. Et si nous voulions spécifier les membres lors de la création, sans avoir à compter sur les propriétés expando et l'affectation post-création ?

C'est là que la notation littérale des objets peut être utile :

var obj1 = {Name:"A Person",TelNo="12345"};  

Ici, nous avons obtenu le même effet en une seule ligne de code et avec beaucoup moins de caractères.

Une discussion plus approfondie des méthodes de construction d'objets ci-dessus peut être trouvée à l'adresse suivante : JavaScript et la programmation orientée objet (OOP).

Et enfin, qu'en est-il de l'idiot qui a passé outre l'objet ? Vous pensiez que ce n'était pas possible ? Bon, ce JSFiddle prouve le contraire. L'utilisation de la notation littérale objet nous évite de tomber dans cette bouffonnerie.

(De http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/ )

1 votes

Que pensez-vous de Object.Create ? Voir : developer.mozilla.org/fr/US/docs/Web/JavaScript/Référence/

0 votes

Si vous préférez privilégier les littéraux d'objets aux new Object() en raison de la possibilité que quelque chose écrase la fonction Object, vous devriez également écrire des gardes un peu partout lorsque vous utilisez des assistants comme Object.keys pour s'assurer qu'il n'est pas indéfini, ce qui tombe dans l'absurde. Je recommanderais toujours aux gens d'utiliser la notation littérale, mais je pense que cet argument particulier s'effondre quand on pense aux conséquences de cette façon de penser.

1 votes

Erreur de syntaxe : Unxpected token '='. Un ':' est attendu après le nom de la propriété 'TelNo'.

45voto

areyoueye Points 71

Sur ma machine utilisant Node.js, j'ai exécuté ce qui suit :

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

Notez qu'il s'agit d'une extension de ce qui se trouve ici : Pourquoi arr = [] est-il plus rapide que arr = new Array ?

mon résultat était le suivant :

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

Il est donc clair que {} et [] sont plus rapides que l'utilisation de new pour créer des objets/rays vides.

3 votes

J'ai l'impression que c'est la réponse que la question cherchait vraiment, même si j'aurais aimé que cela soit testé en plus sur un objet avec quelques propriétés pour être sûr.

2 votes

Des chiffres intéressants. Il y a des gens qui doivent être conscients de cela, mais je retiens que l'allocation de 200 000 objets, même maigres, ne me coûtera que 5,6 ms, donc je ne vais pas m'en inquiéter.

0 votes

Sur Node 10.13.0 les choses ONT CHANGÉ Testing Array : using[] : 117.178ms using new : 116.947ms Testing Object : using{} : 116.252ms using new : 115.910ms

34voto

Jermin Bazazian Points 767

Tout le monde ici parle des similitudes entre les deux. Je vais souligner les différences.

  1. Utilisation de new Object() permet de passer un autre objet. Le résultat évident est que l'objet nouvellement créé sera défini par la même référence. Voici un exemple de code :

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
  2. L'utilisation n'est pas limitée aux objets comme dans les objets OOP. D'autres types peuvent également lui être passés. La fonction définira le type en conséquence. Par exemple, si nous lui passons l'entier 1, un objet de type nombre sera créé pour nous.

    var obj = new Object(1);
    typeof obj // "number"
  3. L'objet créé à l'aide de la méthode ci-dessus ( new Object(1) ) serait converti en type objet si une propriété lui est ajoutée.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
  4. Si l'objet est une copie d'une classe enfant d'objet, nous pouvons ajouter la propriété sans conversion de type.

    var obj = new Object("foo");
    typeof obj // "object"
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = "foo";
    str.a = 1;
    str.a // undefined

3 votes

Je suis très confus au sujet des deux dernières lignes Pourquoi si vous assignez à str.a la valeur 1, str.a est indéfini ? @Jermin Bazazin

3 votes

@AndreaScarafoni parce que str est de type string Vous ne pouvez donc pas lui attribuer une propriété. jsfiddle.net/grq6hdx7/1

1 votes

La réponse à la question 4 a-t-elle changé ? J'obtiens false, not true, dans la dernière version de Chrome 53. var obj = new Object("foo"); typeof obj; obj === "foo" // true

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X