Structures in Javascript

Eerder, toen ik een aantal gerelateerde variabelen moest opslaan, zou ik een klasse maken.

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')
];

Maar ik vraag me af of dit een goede praktijk is. Zijn er andere, beter manieren om een ​​struct te simuleren in JavaScript?


Antwoord 1, Autoriteit 100%

Het enige verschil tussen objectletterijen en geconstrueerde objecten zijn de eigenschappen die zijn geërfd van het prototype.

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

je zou een struct fabriek kunnen maken.

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

Antwoord 2, Autoriteit 18%

Ik gebruik altijd objectliteralen

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

Antwoord 3, Autoriteit 11%

Het echte probleem is dat de structuren in een taal zouden worden vermeld om typen geen referentietypen te zijn. De voorgestelde antwoorden suggereren met behulp van objecten (die referentietypen) zijn in plaats van structuren. Hoewel dit zijn doel kan dienen, wijkt het het punt dat een programmeur daadwerkelijk zou willen willen dat de voordelen van het gebruik van waardeverlagen (zoals een primitief) in plaats van referentietype. Waarde typen, voor één, mogen geen geheugenlekken veroorzaken.


Antwoord 4, Autoriteit 5%

Ik denk dat het creëren van een klasse om C-achtige structuren te simuleren, zoals het gaat doen, is de beste manier.

Het is een geweldige manier om gerelateerde gegevens te groeperen en vereenvoudigt het doorgeven van parameters naar functies. Ik zou ook beweren dat een JavaScript-klasse meer lijkt op een C++ Struct dan een C++ -klasse, gezien de extra inspanning nodig Simuleer echte objectgeoriënteerde functies.

Ik heb ontdekt dat het proberen om JavaScript meer op een andere taal te maken, snel gecompliceerd, maar ik steun volledig ondersteund met JavaScript-klassen als functioneloze structuren.


Antwoord 5, Autoriteit 4%

Volgens Markus’s antwoord , in nieuwere versies van JS (ES6 I Think) Je kunt meer een ‘struct’ fabriek maken Gewoon gebruiken pijlfuncties en rustparameter zoals SO:

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);

Het resultaat van het uitvoeren van deze is:

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

U kan het lijken op namedtuple Python’s:

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);

En de resultaten:

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

Antwoord 6, Autoriteit 2%

Ik gebruik voorwerpen JSON stijl voor stom structuren (geen lid functies).


Antwoord 7

Het is meer werk op te zetten, maar als onderhoudbaarheid verslaat eenmalige inspanning dan kan dit uw geval te zijn.

/**
 * @class
 */
class Reference {
    /**
     * @constructs Reference
     * @param {Object} p The properties.
     * @param {String} p.class The class name.
     * @param {String} p.field The field name.
     */
    constructor(p={}) {
        this.class = p.class;
        this.field = p.field;
    }
}

Voordelen:

  • niet gebonden aan argument order
  • makkelijk uit te breiden
  • script type ondersteuning:


Antwoord 8

Ik heb een kleine bibliotheek gemaakt om struct te definiëren als je met ES6-compatibiliteit werkt.

Het is een JKT-parser. U kunt de projectrepository hier bekijken JKT-parser

U kunt bijvoorbeeld uw struct als volgt maken

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 

Antwoord 9

Dit is een oud probleem dat nog niet is opgelost. Voor wat het waard is, ik gebruik onveranderlijkheid om soortgelijk gedrag te krijgen. Typescript gebruiken:

export class Point {
   public readonly X: number;
   public readonly Y: number;
   constructor(x: number, y: number)
   {
       this.X = x;
       this.Y = y;
   }
   public static SetX(value: number) : Point {
       return new Point(value, this.Y);
   }
   public static SetY(value: number) : Point {
       return new Point(this.X, value);
   }
}

Hierdoor krijgt u een belangrijk voordeel van een complex waardetype, namelijk dat u het object niet per ongeluk kunt wijzigen via een verwijzing ernaar.

Het nadeel is natuurlijk dat als je een lid WEL wilt wijzigen, je een nieuwe instantie moet maken, vandaar de statische functies SetXen SetY.

Het is een heleboel syntactische suiker, maar ik denk dat het de moeite waard is voor speciale gevallen, zoals Point, die mogelijk veel kan worden gebruikt en tot veel bugs kan leiden als de waarden per ongeluk worden gewijzigd.

Other episodes