Javascript 理解循环函数

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

欢迎,

关于主题正确答案的问题:

我不明白这个“getDeepKeys”函数是如何工作的。我知道有很多关于这个话题的帖子,但它们并没有给我问题的完整答案

我的问题详情如下:

  • 我正在测试函数的一段代码:
  • 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这是一个很好的可视化工具。喜欢它:)