gpt4 book ai didi

javascript - 无法理解此展平对象上的 ` recursion and closure scope`

转载 作者:行者123 更新时间:2023-12-03 12:12:54 26 4
gpt4 key购买 nike

我应该压平一个对象,为此我使用这个函数:

var flatter = function(ob){
var f = {};
for(var i in ob) {
if(typeof ob[i] == 'object') {
var newOb = flatter(ob[i]);
for(var x in newOb) {
f[i+'.'+x] = newOb[x];
}
}else{
f[i] = ob[i];
}
}
return f;
}

工作正常。我应用这个对象得到了正确的结果:

var ob = {
"address" : {
"details" : {
"first" : "siva",
"last" : "sankara",
"mam":["mam1","mam2"]
}
}
};

结果是:

reslut : Object {address.details.first: "siva", address.details.last: "sankara", address.details.mam.0: "mam1", address.details.mam.1: "mam2"} 

但是我无法理解我得到的结果。我知道,这是面向递归闭包范围 - 但是搜索谷歌我没有得到任何明确的教程或文章。

有人可以帮助我一步一步地理解这一点吗?

Here is the live demo

提前致谢!

最佳答案

function flatter(ob){
'use strict';
var f = {}, //return this
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
//flatten this object again. Assign result to newOb
var newOb = flatter(ob[key]);
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}

您可以将此代码翻译成类似的内容

function flatter(ob){
'use strict';
var f = {}, //return this object
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
var newOb = (function (ob) {
'use strict';
var f = {}, //return this object
key;
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if(typeof ob[key] === 'object') { //if value is object
var newOb = flatter(ob[key]);
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}(ob[key]));
for(var x in newOb) {
f[key + '.' + x] = newOb[x];
}
} else {
f[key] = ob[key];
}
}
}
return f;
}

主要思想是每个函数调用都可以替换为该函数的主体。
对象本身是一个递归结构,因为可以内容对象。如果给出

{
id: 12345,
name: 'John',
friends: [12346, 75645, 96768]
}

不需要递归。对象不包含任何对象,因此无需额外的函数调用即可将其拉直(顺便说一句,它是扁平的)。如果给出

{
id: 12345,
name: {
first: 'John',
last: 'Doe'
},
friends: [12346, 75645, 96768]
}

然后对象包含对象作为字段。因此,您可以使用 function flatter,其中函数调用被函数体替换。如果给出

{
id: 12345,
name: {
first: 'Helen',
last: {
beforeMarriage: 'Dobsky',
afterMarriage: 'Bobsky'
}
},
friends: [12346, 75645, 96768]
}

那么就不能没有 3 个函数调用。所以你可以将函数体复制三遍。但是,对象可以具有[无限]非常深的结构。因此嵌套函数体的数量未知。因此,使用递归调用代替将函数体嵌套到函数中。
递归函数应该至少有一个退出点以避免无限递归

return f;

在我们的例子中。由于对象中的字段数量是有限的,因此可以到达该退出点。这不是解决任务的唯一方法。由于对象看起来像树(一种)递归可以用堆栈代替,堆栈保留复杂的字段,并在处理简单字段后返回到对象堆栈并在循环中处理它们。

堆栈实现。不漂亮,但有用)

function iflatter(input) {
'use strict';
var f = {}, //return this object
key,
stack = [],
ob,
prefix,
name;
stack.push(["", input]);
while (stack.length != 0) {
[prefix, ob] = stack.pop();
for(key in ob) { //for each key
if (ob.hasOwnProperty(key)) {
if (prefix !== "") {
name = prefix + "." + key;
} else {
name = key;
}
if(typeof ob[key] === 'object') {
stack.push([name, ob[key]]);
} else {
f[name] = ob[key];
}
}
}
}
return f;
}

关于javascript - 无法理解此展平对象上的 ` recursion and closure scope`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24880182/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com