代码之家  ›  专栏  ›  技术社区  ›  nickf

javascript中的结构

  •  89
  • nickf  · 技术社区  · 16 年前

    以前,当我需要存储一些相关变量时,我会创建一个类。

    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中模拟结构的方法?

    7 回复  |  直到 6 年前
        1
  •  160
  •   Markus Jarderot    16 年前

    对象文本和构造对象之间的唯一区别是从原型继承的属性。

    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
    
        2
  •  25
  •   vava    16 年前

    我总是使用对象文本

    {id: 1, speaker:"john", country: "au"}
    
        3
  •  11
  •   Mario Narcis Radoi    8 年前

    真正的问题是语言中的结构应该是值类型,而不是引用类型。建议的答案建议使用对象(参考类型)代替结构。虽然这可以达到它的目的,但它回避了这样一点:程序员实际上希望使用值类型(如原语)代替引用类型的好处。例如,值类型不应该导致内存泄漏。

        4
  •  7
  •   peter    13 年前

    我认为创建一个类来模拟类C结构,就像您所做的那样,是 最好的 方式。

    这是一种将相关数据分组并简化向函数传递参数的好方法。我还认为,JavaScript类更像C++结构而不是C++类,考虑到 added effort 需要模拟真实的面向对象特性。

    我发现,试图使javascript更像另一种语言的做法很快变得复杂起来,但我完全支持将javascript类用作无功能结构。

        5
  •  3
  •   typoerrpr    7 年前

    跟随马库斯的 answer ,在较新版本的JS(我认为是ES6)中,您可以更简单地使用 Arrow Functions 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的名称duple:

    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
    
        6
  •  2
  •   Robert Gould    16 年前

    我将对象JSON样式用于哑结构(没有成员函数)。

        7
  •  0
  •   Aditya Kresna Permana    6 年前

    如果您使用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