Javascript 理解循环函数
欢迎, 关于主题正确答案的问题: 我不明白这个“getDeepKeys”函数是如何工作的。我知道有很多关于这个话题的帖子,但它们并没有给我问题的完整答案 我的问题详情如下:Javascript 理解循环函数,javascript,recursion,Javascript,Recursion,欢迎, 关于主题正确答案的问题: 我不明白这个“getDeepKeys”函数是如何工作的。我知道有很多关于这个话题的帖子,但它们并没有给我问题的完整答案 我的问题详情如下: 我正在测试函数的一段代码: var数据2={ 订单信息:{ EntityId:“ZZ-KR/00000002/2020/1”, 买方1:{ GLN:“GLN.63401346\u买方\u 1”, }, 卖家1:{ GLN:“GLN.63401346\u卖方1”, }, }, 订单响应消息:{ 标准:“标准名称”, 买方2
var数据2={
订单信息:{
EntityId:“ZZ-KR/00000002/2020/1”,
买方1:{
GLN:“GLN.63401346\u买方\u 1”,
},
卖家1:{
GLN:“GLN.63401346\u卖方1”,
},
},
订单响应消息:{
标准:“标准名称”,
买方2:{
GLN:“GLN.6340134346”
},
卖家2:{
GLN:“GLN.7690933887”,
},
}
}
功能getDeepKeys(obj){
var键=[];
for(obj中的var键){
按键。按(键);
if(对象类型[键]=“对象”){
var subkeys=getDeepKeys(obj[key]);
keys=keys.concat(subkeys.map)(函数(子键){
返回键+“+”子键;
}));
}
}
返回键;
}
var objectt=getDeepKeys(数据2);
console.log(objectt)代码>
我现在不明白,如果本应存储数据的arra再次声明在内存中,而最后的函数返回正确的结果,那么该数据是如何存储的
这由concat
调用处理:
var subkeys = getDeepKeys(obj[key]);
keys = keys.concat(subkeys.map(function(subkey) {
return key + "." + subkey;
}));
这一呼吁:
使用getDeepKeys
获取内部调用的键数组
使用map
将key+“
添加到每个键的开头
使用concat
获取一个新数组,其中包含键中的所有内容
加上上面第2列中数组中的所有内容,将该数组分配给键
因此,在递归调用的每个级别,内部递归调用的结果通过concat
添加到“当前”递归调用的结果中。我的理解是,您对getDeepKeys()的不同迭代感到困惑
方法知道它应该将值保存到哪个键
变量
然后在调用函数后,将再次创建一个空键数组
是,它会创建另一个名为keys的变量。但与我们不同的是,人类计算机通过它们在内存中的地址来识别每把钥匙。您可以在方法的不同迭代中声明任意多个同名变量。它们将存储在电脑的不同内存位置。这就是为什么getDeepKeys()
方法永远不会混淆它应该保存阵列的键
假设在创建密钥数组的第一次迭代中,它将存储在内存位置10AD32
,在创建另一个密钥数组的第二次迭代中,它将存储在不同的内存位置,例如11CD34
。因此,尽管这两个变量都有名称键
,但计算机可以对它们进行不同的识别
因此,对于每个迭代,您将有一个不同的keys变量
为了更好地理解,你可以阅读,和
请注意,在描述数组存储过程时,我故意为您过度简化了它。整个阵列不会存储在单个内存位置。实际上,数组名称是指数组头的存储位置。此处的其他答案解释了提供的代码,但问题的根源(您的困惑)是代码本身。递归是一种函数遗产,因此将其与函数风格结合使用会产生最好的结果。这意味着避免突变、变量重新分配和其他副作用。考虑使用一个表达式-< /p>编写的<代码>
const deepKeys=(t,keys=[])=>
对象(t)==t
? 对象
.参赛作品(t)
.flatMap(([k,v])=>deepKeys(v,[…keys,k]))
:[keys.join(“.”)
常量输入=
{OrderMessage:{EntityId:{ZZ-KR/00000002/2020/1],买方1:{GLN:{GLN.63401346_买方1},卖方1:{GLN:{GLN.63401346_卖方1},订单响应消息:{标准:“标准名称”,买方2:{GLN:{GLN.63401346},卖方2:{GLN:{GLN.7690933887}
for(深度键的常量路径(输入))
console.log(path)
只是一个旁注:getDeepKeys
并不是特别有效,它创建了很多对象,并且不必要地复制了很多东西。(即使执行FP,至少您希望将前缀传递给内部调用…)从对象树获取所有键可能并不重要(可能不会有那么多键),但我不会将该模式推广到更大的领域,比如递归获取目录结构中所有文件的列表,不注意它是否影响性能,如果影响了性能,则准备处理它。为连续函数调用创建的数组与为前一个调用创建的数组不同。可视化代码的执行方式可能会对您有所帮助:每次调用getDeepKeys
,函数都会在对象的特定深度处获取键。这些密钥需要存储在临时位置,并返回给调用方。这就是键的用途:它存储该调用的工作。它被返回,调用方将与其自己的键合并,或者如果是第一次调用,它将只返回该数组。@marzelin这是一个很好的可视化工具。喜欢它:)