JavaScript嵌套对象转数组:console.log正常但push失效原因咨询
问题描述
当存在嵌套对象时,常规for in循环无法完成遍历。通过搜索得知需编写递归函数判断属性是否为对象,于是编写了如下递归函数:
function isObject(value){ return (typeof(value)==='object'); }
function listToArray(list){ let arr=[]; for (let elem in list){ if(isObject(list[elem])===false){ console.log(list[elem]); } else if (isObject(list[elem])){ listToArray(list[elem]); } } return arr; }
该函数可遍历所有嵌套对象并通过console.log输出所有非对象属性值,但返回空数组。当将console.log替换为arr.push时,仅能推入最外层对象中的非对象属性。
示例对象:
let list = { value : 1, rest: { value:2, rest:{value:3, rest:null} } }
预期listToArray(list)返回[1,2,3],想了解为何console.log正常而push失效。
原因分析
console.log能正常输出的原因:
console.log是全局输出方法,不管在递归的哪一层函数调用中执行,都会直接把内容打印到控制台,不受当前函数作用域限制。所以遍历嵌套对象时,内层递归里的console.log同样能输出对应属性值。push仅能处理外层属性的核心原因:每次调用
listToArray时,都会创建一个独立的新数组arr。当递归调用listToArray(list[elem])时,内层函数会生成自己的数组并收集嵌套属性的值,但你没有把内层数组的内容合并到外层的arr中。
举个实际执行流程:
- 第一次调用
listToArray(list),创建外层数组arr,将value:1push进去,随后遇到rest对象,调用内层listToArray(rest)。 - 内层调用创建自己的
arr,pushvalue:2,再遇到rest继续递归。 - 最内层调用push
value:3后返回数组[3],但这个返回值没有被外层函数接收并合并到外层数组里,最终外层数组只保留了[1]。
原代码中递归调用时仅执行listToArray(list[elem]),完全忽略了内层函数返回的数组,导致嵌套属性的值无法被收集到外层的结果数组中。
内容的提问来源于stack exchange,提问作者KarimMaged
相关产品推荐
相关产品推荐

