web-dev-qa-db-ja.com

Javascriptの構造

以前は、いくつかの関連変数を保存する必要があったときに、クラスを作成していました。

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

しかし、これが良い習慣かどうか疑問に思っています。 Javascriptで構造体をシミュレートする他のより良い方法はありますか?

95
nickf

オブジェクトリテラルと構築されたオブジェクトの唯一の違いは、プロトタイプから継承されたプロパティです。

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

構造体ファクトリを作成できます。

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
166
Markus Jarderot

私は常にオブジェクトリテラルを使用します

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

実際の問題は、言語の構造が参照型ではなく値型であると想定されていることです。提案された回答は、構造の代わりにオブジェクト(参照型)を使用することを提案しています。これは目的を果たすことができますが、参照型の代わりに値型(プリミティブなど)を使用する利点をプログラマが実際に望んでいるという点を回避します。たとえば、値の種類によってメモリリークが発生することはありません。

15
Mario

あなたがやってきたように、Cのような構造体をシミュレートするクラスを作成することがbestの方法だと思います。

関連データをグループ化し、関数へのパラメーターの受け渡しを簡素化するのに最適な方法です。また、実際のオブジェクト指向機能をシミュレートするために必要な 追加の労力 を考慮すると、JavaScriptクラスはC++クラスよりもC++構造体に似ていると主張します。

JavaScriptを別の言語のようにしようとすると、すぐに複雑になりますが、JavaScriptクラスを機能のない構造体として使用することを完全にサポートしています。

8
peter

Markusの answer に従い、JSの新しいバージョン(ES6と思います)では、 矢印関数 および Rest Parameter を使用して、より簡単に「構造体」ファクトリを作成できます=そのように:

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

これを実行した結果は次のとおりです。

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

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

そして結果:

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

オブジェクトのJSONスタイルをダム構造(メンバー関数なし)に使用します。

2
Robert Gould

ES6との互換性がある場合、構造体を定義する小さなライブラリを作成しました。

ここでプロジェクトリポジトリをチェックアウトできるJKTパーサー JKT Parser

例として、このような構造体を作成できます

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