什么时候对象应该包含其他对象而不是对其他对象的引用?

时间:2014-12-22 17:37:51

标签: javascript oop

在某些情况下,一种方法比另一种方法更好还是有可接受的最佳实践?"以下面的例子为例:

project:{
  team:{
    testers:{
      1 : {first: 'employee', last: 'one'},
      2 : {first: 'employee', last: 'two'}
    },
    experts:{
      1 : {first: 'employee', last: 'one'},
      3 : {first: 'employee', last: 'three'}
    }
  }
};
employees:{
  1 : {first: 'employee', last: 'one'},
  2 : {first: 'employee', last: 'two'},
  3 : {first: 'employee', last: 'three'}
};

VS

project:{
  team:{
    testers:[1,2],
    experts:[1,3]
  }
};
employees:{
  1 : {first: 'employee', last: 'one'},
  2 : {first: 'employee', last: 'two'},
  3 : {first: 'employee', last: 'three'}
};

VS

project:{
  team:{
    testers:[
      {id: 1, first: 'first', last: 'one'},
      {id: 2, first: 'employee', last: 'two'}
    ],
    experts:{
      {id: 1, first: 'employee', last: 'one'},
      {id: 3, first: 'employee', last: 'three'}
    }
  }
};
employees:[
  {id: 1, first: 'employee', last: 'one'},
  {id: 2, first: 'employee', last: 'two'},
  {id: 3, first: 'employee', last: 'three'}
];

让我们添加一个非常具体的情况。我正在使用把手模板和多选。我想创建一个多选列表,列出所有有资格成为专家的员工,同时还预先选择已被确定为项目专家的员工。如果我使用的是示例3 ,我必须执行以下操作来构建我的多选项:

 for(var x in employees){
   var found = 0;
   for(var y in project.team.experts){
     if(project.team.experts.[y] === employees[x].id){
        found = 1;
     }
   }
   if(found){
      //Print selected option
   } else {
     //Print unselected option
   }
 }

但是,如果我使用示例1

for(var x in employees){
  if(typeof project.team.experts[employees[x].id] !== 'undefined'){
    //Print selected option
  } else {
    //Print unselected option
  }
}

5 个答案:

答案 0 :(得分:1)

我认为这取决于您将使用的对象。
您可以使用(json)对象发送到API,提供模板,在对象之间进行通信,根据需要提取值等等。

格式的主要内容是:

employees:{
  1 : {first: 'employee', last: 'one'},
  2 : {first: 'employee', last: 'two'},
  3 : {first: 'employee', last: 'three'}
};

以下列格式更有意义:

employees: [{id: 1, name: "John"}, {id: 2, name: "Kim"}]; 

因为员工是对象(数组)的集合而不是单个对象 这将使您更容易提取数据或对对象执行操作 我不确定firstlast参数应该是什么意思,但我认为使对象属性具有描述性(给它们清晰的名称)也是一个好主意。

但我认为这种情况非常依赖 也许有一天,你需要以下列格式发送一个对象作为URL搜索参数,以符合某些api的要求:

{employees: "1, 2, 3"} 

答案 1 :(得分:0)

如果引用你的意思是索引数组([1, 2]),那么这样做是有风险的......这会降低代码的可读性。

简单比较:

// Directly gives me the employee
project.team.testers[1];

// I have to pass an index to the employee
employees[project.team.testers[1]];

一个名为testers的字段应该包含测试人员,也就是说员工,而不是数组中的索引或员工的哈希,不应该是吗?

答案 2 :(得分:0)

我认为你有点混淆术语。对象永远不包含其他对象,它们包含引用到其他对象。但是这个引用与问题标题中的引用具有不同的语义。哪种id有外部手段将其解析为实例。

接下来,在您的第一个示例中,您实际拥有两名员工last:'one'project.team.testers[1]project.team.experts[1]不同的对象。

接下来,您使用数字作为键。这不是很好,因为在这里很容易将对象误认为数组(然后想知道为什么专家[0]不存在)。

现在,问你的问题。第一个片段很自然。

对于第二个代码段,您不必直接引用对象,而是设置一些您以后需要解决的ID。问题是,这样做的原因是什么 - 或何时有意义/有必要。我能想象的是什么:

  • 对象(如员工ID)有些自然。
  • ID /对象maping是某种方式" central"到应用程序。
  • Ids比对象实例更长寿。
  • 目标对象没有硬引用,因此可以对它们进行垃圾回收。
  • 如果不使用ID,您实际上需要创建目标对象的副本,因此使用ID实际上可以节省内存,这很重要。

答案 3 :(得分:0)

这是一种错误的二分法。您可能正在考虑关系数据库建模术语。你只需要:

var employees: [
    {first: 'employee', last: 'one'},
    {first: 'employee', last: 'two'},
    {first: 'employee', last: 'three'}
];

var project = {
    team:{
        testers: [employees[0], employees[1]],
        experts: [employees[0], employees[2]]
    }
};

换句话说,不是存储索引或索引数组,而是存储对象本身的引用。

如果您愿意,employees可以是哈希,例如:

var employees = {
    employeeOne:   {first: 'employee', last: 'one'},
    employeeTwo:   {first: 'employee', last: 'two'},
    employeeThree: {first: 'employee', last: 'three'}
};

var project = {
    team:{
        testers: [employeeOne, employeeTwo],
        experts: [employeeOne, employeeThree]
    }
};

答案 4 :(得分:0)

我建议使用索引而不是引用,因为:

  1. 您可以轻松地从服务器加载数据,因为您不需要make reference;
  2. 你是一个人,因为当你删除对象时你可以忘记删除所有引用,因此更难捕获bug;
  3. 您可以轻松地对数据进行排序或过滤,因为您需要的所有内容 - 使用正确的索引顺序获取数组:

    项目:{   球队:{     测试:[1,2,5,6,9],     专家:[1,3]   },   teamSortedСontribution:{     测试:[9,5,1,2,6],     专家:[3,1]   },   teamFiltratedJavascript:{     测试:[9,5],     专家:[1]   } };

  4. 如果您使用node.js并保持对象之间的引用并尝试扩展您的程序,您可能会遇到麻烦,因为node.js没有共享内存。