web-dev-qa-db-fra.com

Structs en Javascript

Auparavant, lorsque je devais stocker un nombre de variables liées, je créais une classe.

function Item(id, speaker, country) {
    this.id = id;
    this.speaker = spkr;
    this.country = country;
}
var myItems = [
    new Item(1, 'john', 'au'),
    new Item(2, 'mary', 'us')
];

Mais je me demande si c'est une bonne pratique. Existe-t-il d'autres moyens mieux de simuler une structure en Javascript?

89
nickf

Les seules différences entre les littéraux d'objet et les objets construits sont les propriétés héritées du prototype.

var o = {
  'a': 3, 'b': 4,
  'doStuff': function() {
    alert(this.a + this.b);
  }
};
o.doStuff(); // displays: 7

Vous pourriez faire une usine de struct.

function makeStruct(names) {
  var names = names.split(' ');
  var count = names.length;
  function constructor() {
    for (var i = 0; i < count; i++) {
      this[names[i]] = arguments[i];
    }
  }
  return constructor;
}

var Item = makeStruct("id speaker country");
var row = new Item(1, 'john', 'au');
alert(row.speaker); // displays: john
160
Markus Jarderot

J'utilise toujours des littéraux d'objet

{id: 1, speaker:"john", country: "au"}
25
vava

Le vrai problème est que les structures dans un langage sont supposées être des types de valeur et non des types de référence. Les réponses proposées suggèrent d'utiliser des objets (qui sont des types de référence) à la place des structures. Bien que cela puisse remplir sa fonction, il élimine le fait qu'un programmeur voudrait réellement bénéficier des avantages de l'utilisation de types de valeur (comme une primitive) au lieu d'un type de référence. Les types de valeur, par exemple, ne devraient pas causer de fuites de mémoire.

12
Mario

Je pense que créer une classe pour simuler des structures de type C, comme vous l’avez fait, est le moyen meilleur

C'est un excellent moyen de regrouper des données liées et simplifie la transmission de paramètres à des fonctions. Je dirais également qu'une classe JavaScript ressemble plus à une structure C++ qu'à une classe C++, en considérant le effort supplémentaire nécessaire pour simuler de véritables fonctionnalités orientées objet. 

J'ai constaté qu'essayer de rendre JavaScript plus semblable à un autre langage devenait rapidement compliqué, mais je suis entièrement favorable à l'utilisation de classes JavaScript en tant que structures non fonctionnelles.

7
peter

Suivant les commandes answer de Markus, dans les versions les plus récentes de JS (ES6, je pense), vous pouvez créer une fabrique 'struct' plus simplement en utilisant Fonctions de flèche et Paramètre de repos comme ceci:

const Struct = (...keys) => ((...v) => keys.reduce((o, k, i) => {o[k] = v[i]; return o} , {}))
const Item = Struct('id', 'speaker', 'country')
var myItems = [
    Item(1, 'john', 'au'),
    Item(2, 'mary', 'us')
];

console.log(myItems);
console.log(myItems[0].id);
console.log(myItems[0].speaker);
console.log(myItems[0].country);

Le résultat de cette opération est:

[ { id: 1, speaker: 'john', country: 'au' },
  { id: 2, speaker: 'mary', country: 'us' } ]
1
john
au

Vous pouvez faire en sorte qu'il ressemble à celui de namedtuple:

const NamedStruct = (name, ...keys) => ((...v) => keys.reduce((o, k, i) => {o[k] = v[i]; return o} , {_name: name}))
const Item = NamedStruct('Item', 'id', 'speaker', 'country')
var myItems = [
    Item(1, 'john', 'au'),
    Item(2, 'mary', 'us')
];

console.log(myItems);
console.log(myItems[0].id);
console.log(myItems[0].speaker);
console.log(myItems[0].country);

Et les résultats:

[ { _name: 'Item', id: 1, speaker: 'john', country: 'au' },
  { _name: 'Item', id: 2, speaker: 'mary', country: 'us' } ]
1
john
au
3
typoerrpr

J'utilise des objets de style JSON pour des structures dumb (pas de fonctions membres).

2
Robert Gould

J'ai créé une petite bibliothèque pour définir struct si vous travaillez avec la compatibilité ES6.

C’est un analyseur JKT, vous pouvez consulter le référentiel de projet ici Analyseur JKT

Pour un exemple, vous pouvez créer votre structure comme ceci

const Person = jkt`
    name: String
    age: Number
`

const someVar = Person({ name: "Aditya", age: "26" })

someVar.name // print "Aditya"
someVar.age // print 26 (integer)

someVar.toJSON() // produce json object with defined schema 
0
Aditya Kresna Permana