今天又又面试字节了,这次倒在了二面,至少比上次更进一步吧,希望未来有去大厂开开眼的机会。说说今天的一道面试题吧。

JSON.stringfy() 的 circular structure

让我们先来假设这样一个场景

let b = {}, c = {};
let a = { b : b, c : c };
b.d = a;
JSON.stringify(a);

JSON.stringify() 的结果会是什么呢?结果是Uncaught TypeError: Converting circular structure to JSON。因为在 b 对象中存在对 a 对象的引用。这个 ? 是这样,但举一反三准确地归纳出 circular structure 的条件也是个不小的挑战,推荐大家停顿一下思考一会。。。答案是当子对象对父对象引用时,如果用树形结构图来描述的的话就是。
image
图中(1)和(2)会导致循环结构,而(3)不会

基本思路

弄清楚会导致循环结构报错的条件后这个问题就没有那么复杂了,但面试的时候却卡在了这里,只能说画好图很重要吧。。。直观的做法是用递归的方式深度遍历并保存路径上的父节点。举例来说,当遍历到 d 时,parents = [a,b]。同时不要忘记遍历完 d 返回的时候消除副作用,也就是删除添加的点 b,这在很多需要输出路径的二叉树遍历中都是很重要却又容易忘记的一步

上代码喽

function circularRefference(obj){
    let initArr = [obj];
    return circularRefferenceHelper(obj,initArr);
}
function circularRefferenceHelper(obj,parents){
    for(let key in obj){
        if (typeof obj[key] === 'object'){
            if(parents.includes(obj[key])){
                return true;
            }else{
                parents.push(obj[key]);
                let res = circularRefferenceHelper(obj[key],parents);
                parents.pop();
                if (res){ return res;}
            }
        }
    }
    return false;
}

彩蛋

学了js半年,之前都是感觉 js 的弱类型和动态化大法好,今天面试的时候也算是被上了一课了。 ['1','2','3'].map(parseInt) 的输出会是多少呢?如果和我一样还没发现这是个坑的可以去跑一下。至于结果为什么这样提示从 parseInt 的参数个数还有 map 内函数的参数个数的找找原因。


蓝猫太胖飞不动
1 声望0 粉丝

front-end gogogo