Javascript中的结构

nic*_*ckf 99 javascript struct

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

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')
];
Run Code Online (Sandbox Code Playgroud)

但我想知道这是不是一个好习惯.还有其他更好的方法来模拟Javascript中的结构吗?

Mar*_*rot 170

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

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

你可以做一个结构工厂.

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
Run Code Online (Sandbox Code Playgroud)

  • ......然后我理解了工厂的功能.+1以获得清晰,易懂,简洁的答案以及工厂示例. (25认同)
  • 我很好奇这种方法相对于对象文字的效率。 (3认同)

vav*_*ava 26

我总是使用对象文字

{id: 1, speaker:"john", country: "au"}
Run Code Online (Sandbox Code Playgroud)

  • 它与类的解决方案完全一样可维护,因为JavaScript不关心您调用函数的参数数量.如果您使用Emacs等正确的工具,重新排序不是问题.而且你可以看到什么等于错误的东西,比如交换参数已经过时了. (4认同)
  • 但最大的专业是你会写更少的代码,它会更干净:) (3认同)
  • @vava 重新输入仍然是一个问题,因为比复制新的 ___ ( , , , ) 原型有更多的跳转。此外,没有可读性。一旦你习惯了编码,`new READABLE_PART(ignore everything in here)` 变得非常易于扫描和自我记录,而不是`{read: "ignore", everything: "ignore", in: "ignore", here: " ignore"} // 然后在你的脑海中想出 READABLE_PART`。第一个版本在快速翻页时可读。第二,你重构为结构只是为了理解。 (3认同)
  • 这样会更难维护(将来是否要添加一个新字段)以及更多代码(每次重新键入“ id”,“ speaker”和“ country”)? (2认同)

Mar*_*rio 16

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


pet*_*ter 8

我认为创建一个类来模拟类似C的结构,就像你一直在做的那样,是最好的方法.

这是分组相关数据并简化将参数传递给函数的好方法.我还认为,考虑到模拟真实面向对象特性所需的额外工作,JavaScript类更像是C++结构而不是C++类.

我发现尝试使JavaScript更像另一种语言变得复杂很快,但我完全支持使用JavaScript类作为无功能结构.

  • 我希望有像结构体、元组这样的东西——允许强类型数据集合的东西——在编译时处理并且没有像对象这样的哈希图的开销 (2认同)

typ*_*rpr 7

按照 Markus 的回答,在较新版本的 JS(我认为是 ES6)中,您可以更简单地使用箭头函数Rest 参数创建一个“结构”工厂,如下所示:

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);
Run Code Online (Sandbox Code Playgroud)

运行结果如下:

[ { id: 1, speaker: 'john', country: 'au' },
  { id: 2, speaker: 'mary', country: 'us' } ]
1
john
au
Run Code Online (Sandbox Code Playgroud)

你可以让它看起来类似于 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);
Run Code Online (Sandbox Code Playgroud)

结果:

[ { _name: 'Item', id: 1, speaker: 'john', country: 'au' },
  { _name: 'Item', id: 2, speaker: 'mary', country: 'us' } ]
1
john
au
Run Code Online (Sandbox Code Playgroud)