【问题标题】:Javascript Recursion Issue - deeply nested objectJavascript递归问题 - 深度嵌套的对象
【发布时间】:2021-08-10 09:52:38
【问题描述】:

我有一个函数可以遍历对象的密钥并查找敏感密钥,例如电子邮件、密钥、密码、apiKey、secrets、secret 和 userKey。

如果它发现任何有值,它会编辑该值。

但是,它有时会出现以下错误:

"RangeError: Maximum call stack size exceeded"

Whats causing the endless recursion??

const deepObjectRedactor = obj => {
  const sensitiveKeys = [
    'email',
    'key',
    'password',
    'apiKey',
    'secrets',
    'secret',
    'userKey'
  ];
  Object.keys(obj).forEach(key => {
    if (
      sensitiveKeys.map(e => e.toLowerCase()).includes(key.toLowerCase()) &&
      obj[key]
    ) {
      obj[key] = '**********';
      return;
    }

    if (obj[key] && typeof obj[key] === 'object') {
      deepObjectRedactor(obj[key]);
    }
  });
};


// function invoking the redactor

const customRedactorFormat = info => {
  if (info.message && typeof info.message === 'object') {
    deepObjectRedactor(info.message);
  }
  return info;
});

【问题讨论】:

  • 表示达到内存限制。
  • 不满足递归基本情况。
  • sensitiveKeys.find 而不是sensitiveKeys.map 可能是问题之一。
  • 可能是,对象中某处存在循环。由于您的函数不会跟踪已经 seen 对象,因此您将无限递归。还有你的条件很尴尬,为什么不简单:sensitiveKeys.includes(key.toLowerCase());sensitiveKeys 是一个常量in 你的函数。如果您希望它们全部小写,请将它们定义为全部小写。而不是一遍又一遍地小写它们。
  • @nishkaush 你能提供你的object的简化变体吗

标签: javascript object recursion


【解决方案1】:

您可以编写适用于对象和数组的通用map。然后把redact写成map的特化——

function map (t, f)
{ switch (t?.constructor)
  { case Array:
      return t.map((v, k) => f(k, map(v, f)))
    case Object:
      return Object.fromEntries(
        Object.entries(t).map(([k, v]) => [k, f(k, map(v, f))])
      )
    default:
      return t
  }
}

const redact = (t, keys = new Set) =>
  map(t, (k, v) => keys.has(k) ? "*****" : v)
  
const data =
  [ { user: 1, cc: 1234, password: "foo" }
  , { nested: [ { a: 1, pin: 999 }, { b: 2, pin: 333 } ] }
  , { deeply: [ { nested: [ { user: 2, password: "here" } ] } ] }
  ]
  
console.log(redact(data, new Set(["cc", "password", "pin"])))
[
  {
    "user": 1,
    "cc": "*****",
    "password": "*****"
  },
  {
    "nested": [
      {
        "a": 1,
        "pin": "*****"
      },
      {
        "b": 2,
        "pin": "*****"
      }
    ]
  },
  {
    "deeply": [
      {
        "nested": [
          {
            "user": 2,
            "password": "*****"
          }
        ]
      }
    ]
  }
]

【讨论】:

  • 代码比 OP 的代码干净得多,但 OP 的代码在您的示例 data 对象上具有完全相同的结果。我相当肯定他们的问题在于他们试图递归的对象(可能是循环引用)。 jsfiddle.net/o6fhbLxr
猜你喜欢
  • 2019-08-22
  • 2018-02-14
  • 2016-08-16
  • 1970-01-01
  • 2012-02-12
  • 2020-09-23
  • 1970-01-01
  • 2020-10-06
  • 2020-01-26
相关资源
最近更新 更多