Javascript 获取不同的母节点和子节点(理解代码)
问题 我有一个JSON文件。一小部分看起来像这样Javascript 获取不同的母节点和子节点(理解代码),javascript,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,
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));
我的问题
我对两个部分感到困惑
1)按姓名[人名]=人代码>
我们到底为什么要这样做?它实现了什么?byName[person.name]
是什么意思,为什么它要存储所有人的条目
2)
return byName[person.mother] != null;
}).map(function(person) {
return person.born - byName[person.mother].born;
});
据我所知,第一部分是检查一个人是否真的有母亲。但这是如何运行的?是否只有当某人真的有母亲时才有地图?如果有人没有母亲会怎么样
感谢您的帮助。从较高的层次上讲,该代码的作用是:
构建按姓名键入的人的地图(例如,将键映射到值的对象)
筛选人员数组,筛选出其person.mother
值不是地图中键的人员。(这里有人在挥手。)
映射其余条目(未过滤掉的条目),创建一个新的年龄差异数组
具体问题的详细信息和答案:
1) byName[person.name]=个人代码>
我们到底为什么要这样做?它实现了什么
它使用person.name
的值作为属性名,并使用对该person对象的引用作为值,在由byName
引用的对象中创建属性
因此,当循环完成时,byName
是一个“映射”,如果您愿意的话,它位于人名和人名对象之间
(二)
据我所知,第一部分是检查一个人是否真的有母亲
它正在检查byName
是否具有名称为person.mother
值的属性,如果是,则该属性的值不是null
或未定义的
。坦率地说,这不是一个绝妙的代码
在JavaScript中,当您获取对象的属性值(byName[person.method]
)时,如果对象没有具有该名称的属性,则结果是值未定义。如果对象确实具有具有该名称的属性,则结果是该属性的值-该属性(有点令人困惑)也可能是未定义的
,或者可能是空的
,或者其他任何内容
但是,对于byName
,我们知道它要么是未定义的
(没有匹配的属性),要么是person对象<代码>未定义!=null
是false
,因为当使用松散相等(==
)时,未定义的
和null
是等价的。对于!=空
因此,过滤器所做的是过滤掉person.mother
与byName
中的属性不匹配的条目
是否只有当某人确实有母亲时才使用.map
正确,filter
的结果是一个新数组,它只包含回调返回truthy值的原始数组中的条目
如果有人没有母亲会怎么样
它们被完全排除在最终生成的数组之外。您可以使用浏览器中内置的调试器,逐步查看这些代码,并准确查看发生了什么。搜索有关如何使用浏览器“开发人员工具”的信息,以了解具体操作方法。我强烈建议您执行上述操作(开发人员工具)。没有什么比单步执行代码、检查变量内容等更好的方法来准确理解代码的作用。学着这样做并不难,你大概可以在15分钟内做到。这是一项重要的基本技能,不是只有高级程序员才需要做的。好吧,我现在就试试,但怎么做呢。如果有人真的有母亲,就去做,如果没有,就去做?我的意思是,没有任何声明来检查这个人。妈妈!=空{添加到数组}。你还说它可能是未定义的,所以我们不应该说返回如果=空或!=未定义?@cresjoy:“但它是如何定义的。如果有人真的有母亲……”所有人都有母亲。过滤器
(而不是地图
)所做的是过滤掉那些没有母亲的人,因为她们不会出现在按名字
地图中。因此,filter
返回一个数组,其中只包含person.mother
值与映射中的属性匹配的条目。然后,代码对新数组(不是原始数组)调用map
,创建最终结果。@cresjoy:“你说它可能未定义,那么我们不应该说如果!=null或!=undefined返回吗?”正如我在回答中所说:!”对于未定义的而言,null
将是false
,因为在松散相等(==
和!=
)的情况下,null
和未定义的彼此相等。(还有另外一对运算符,==
和!=
,它们严格,其中null
和未定义的
不相等。)我必须更深入地思考这个问题。我一直在绞尽脑汁去理解这件事。哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦
...filter(function(person) {
return byName[person.mother] != null;
}).map(function(person) {
return person.born - byName[person.mother].born;
});