理解对象的麻烦(获取母节点和子节点之间的年龄差异)

时间:2016-08-02 15:25:49

标签: javascript

我目前正在阅读本书中的一些旧练习,并且在理解对象的关键概念时遇到了一些麻烦,所以这是我的问题。请考虑以下JSON代码

var ANCESTRY_FILE = "[\n  " + [
  '{"name": "Carolus Haverbeke", "sex": "m", "born": 1832, "died": 1905, "father": "Carel Haverbeke", "mother": "Maria van Brussel"}',
  '{"name": "Emma de Milliano", "sex": "f", "born": 1876, "died": 1956, "father": "Petrus de Milliano", "mother": "Sophia van Damme"}',
  '{"name": "Maria de Rycke", "sex": "f", "born": 1683, "died": 1724, "father": "Frederik de Rycke", "mother": "Laurentia van Vlaenderen"}'

问题陈述基本上是为了得到母亲与孩子之间差异的平均值。以下是答案

var ancestry = JSON.parse(ANCESTRY_FILE);
function average(array) {
  function plus(a, b) { return a + b; }
  return array.reduce(plus) / array.length;
}

var byName = {};
ancestry.forEach(function(person) {
  byName[person.name] = person;
});

var differences = ancestry.filter(function(person) {
  return byName[person.mother] != null;
}).map(function(person) {
  return person.born - byName[person.mother].born;
});

console.log(average(differences));

我认为我理解代码,但是我有点困惑为什么有些事情正在以他们的方式发生。首先byName[person.name] = person;使byName对象具有name的键并将其设置为该原始对象。所以基本上可以把它想象成一次迭代

Carolus Haverbeke: '{"name": "Carolus Haverbeke", "sex": "m", "born": 1832, "died": 1905, "father": "Carel Haverbeke", "mother": "Maria van Brussel"}'

现在我的困惑是。如果我尝试console.log(obj[person.mother]),我会得到一堆未定义的值,但有时我得到一个对象?一切都不应该undefined吗?我们从未将obj[person.mother]设置为任何内容。

其次,为什么不能用byName[person.mother] != null;替换person.mother !=null?我们不想根据nulls进行过滤吗?我不知道这两个检查之间有什么区别。

谢谢!

2 个答案:

答案 0 :(得分:1)

这是否可以解释一些事情:

var obj = {};

var parent = { 
  name: 'The Parents Name',
  parent: null
}


var child = { 
  name: 'The childs name',
  parent: 'The Parents Name'
}

obj[parent.name] = parent;
obj[child.name] = child;

console.log(JSON.stringify(obj, null, 2));

当您使用[]引用对象属性时,您指的是属性上的名称,而不是值。即:

var obj = { key: 'value' };

// These two are identical
console.log(obj.key);
console.log(obj['key']);

这也意味着byName[person.mother]返回对象,person.mother返回名称。因此byName[person.name].mother != null;替换为person.mother != null

答案 1 :(得分:1)

我已经设置了一个工作示例,因为你的错误很多,请查看以下代码段: https://repl.it/Cidr

现在,回答你的问题:

  

如果我尝试console.log(obj [person.mother]),我会得到一堆未定义的值,但有时我得到一个对象?不应该一切都不明确吗?我们从未将obj [person.mother]设置为任何东西。

我想通过obj你实际上是指byName(这是一本字典)。 有了这个假设,您将所有数据存储在此字典中。 有时你得到未定义而其他人没有得到的原因是因为有些人的母亲不在列表中,请查看此示例文件:

var ANCESTRY_FILE = "[\n  " + [
  '{"name": "Carolus Haverbeke", "sex": "m", "born": 1832, "died": 1905, "father": "Carel Haverbeke", "mother": "Maria van Brussel"}',
  '{"name": "Emma de Milliano", "sex": "f", "born": 1876, "died": 1956, "father": "Petrus de Milliano", "mother": "Sophia van Damme"}',
  '{"name": "Sophia van Damme", "sex": "f", "born": 1851, "died": 1956, "father": "Petrus de Milliano", "mother": "Someone"}',
  '{"name": "Maria de Rycke", "sex": "f", "born": 1683, "died": 1724, "father": "Frederik de Rycke", "mother": "Laurentia van Vlaenderen"}'
  ] + " ]";
Emma de Milliano是Sophia van Damme的女儿,Sophia在名单中(她出生于1851年),但Carolus Haverbeke是Maria van Brussel的儿子,但Maria不在名单中(我们不是知道关于她的任何事情),所以,如果你试图在字典中找到玛丽亚(byName),你将找不到任何东西。

  

为什么不能byName [person.mother]!= null;用person.mother替换= null?我们不想基于空值进行过滤吗?我不知道这两个检查之间有什么区别。

这个问题也与上一个问题有关。让我们记住相同的示例文件。

如果你试图在字典中找到(byName)某个不在示例文件中的人的名字,它实际上将返回undefined,而不是null,因为该字典没有为该名称定义的值(它没有不存在)。 所以,如果你做person.mother,你将得到那个人的母亲的名字。 但是如果你做byName(person.mother)你不是在询问母亲的名字(一个字符串),你问的是这个人(姓名,性别,出生,死亡,父亲,母亲)实际上是一个对象,而不是一个字符串。

我希望该片段可以帮助您,使用文件添加和删除人员(尤其是母亲),您会立即注意到正在发生的事情。