zhengwei1949 / myblog

个人博客
10 stars 6 forks source link

一道很难的面试题 #135

Open zhengwei1949 opened 6 years ago

zhengwei1949 commented 6 years ago

` 题一 假设,前端需要从一个指定 API 获取数据。根据服务器提供的接口,返回值是一个 JSON 格式的对象。其中, 对象的属性名均为 a, b, c 等无意义的字符串。比如,在下面的例子中,属性 a 记录的是名字, 属性 b 记录的是年龄。然而,显然下面的代码不易理解,因而维护困难。 function getVisitors() { return fetch('https://some.url') .then(response => response.json()) .catch(...); }

function updateFirstVisitor() { getVisitors() .then((visitors) => { if (visitors.length === 0) return; const visitor = visitors[0]; document.querySelector('app').innerHTML = [ '

', Visitor: <span>${visitor.a}</span>, '
', '
', This visitor is <span>${visitor.b}</span> year's old, '
', ].join(''); }) .catch(...); } 现假设服务器端的返回值不能进行修改。如何从前端入手,优化代码的可维护性?请提出解决方案,并给出 相应代码。服务器的返回值,请参考下面给出的说明: 服务器的返回值示例: [{ "a": "xiao ming", "b": "18", "c": [ { "a": "Zootopia", "b": 109, "c": "tt2948356", }, { "a": "Hacksaw Ridge", "b": 139, "c": "tt2119532" }, { "a": "Kiminona", "b": 106, "c": "tt5311514" } ] }] 数据的说明: [{ "名字": "xiao ming", "年龄": "18", "爱看的电影": [ { "名字": "Zootopia", "时长(分)": 109, "IMDb": "tt2948356" }, { "名字": "Hacksaw Ridge", "时长(分)": 139, "IMDb": "tt2119532" }, { "名字": "Kiminona", "时长(分)": 106, "IMDb": "tt5311514" } ] }] 几点注意:

  1. 属性值可能是 primitive, object 或 array
  2. 方案不需要考虑浏览器兼容性。但给出方案后,请注明浏览器的大致兼容范围。
  3. 考虑如果需要结果可序列化,可使用 Object.keys() 取得所有属性,该怎么做?
  4. 如果服务器的返回值非常庞大(比如服务器每次返回数组可能包含上千个对象) 且和服务器的沟通非常频繁(比如每秒一次和服务器进行轮询沟通),解决方案是否会有性能瓶颈? 比如阻塞渲染? `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    // let obj = {n:'小明',a:20};
    // let obj1 = {n:'name',a:'age'};
    // let newObj = {};
    // for(let i in obj){
    //     newObj[obj1[i]] = obj[i];
    // }
    // console.log(newObj);

    // let arr = [{n:'小明1',a:20},{n:'小明2',a:20},{n:'小明3',a:20}];
    // let obj1 = {n:'name',a:'age'};
    // let newArr = [];
    // arr.forEach((item)=>{
    //     let tempObj = {};
    //     for (let i in item) {
    //         tempObj[obj1[i]] = item[i];
    //     }
    //     // console.log(tempObj)
    //     newArr.push(tempObj);
    //     // console.log(newArr)
    // })
    // console.log(newArr);

    let arr = [{
            "a": "xiao ming",
            "b": "18",
            "c": [
                {
                    "a": "Zootopia",
                    "b": 109,
                    "c": "tt2948356",
                },
                {
                    "a": "Hacksaw Ridge",
                    "b": 139,
                    "c": "tt2119532"
                },
                {
                    "a": "Kiminona",
                    "b": 106,
                    "c": "tt5311514"
                }
            ]
        }];

        function transformObj(arr){
            let obj1 = { a: 'name', b: 'time', c: 'IMDb' };
            //先搞定里面一层
            let arr1 = [];
            arr.forEach((item, index) => {
                let myArr = item.c;
                let tempArr = [];
                myArr.forEach((item1, index1) => {
                    let tempObj = {};
                    for (let i in item1) {
                        tempObj[obj1[i]] = item1[i];
                    }
                    tempArr.push(tempObj);
                })
                arr[index].c = tempArr;
            })
            //再搞定外层
            let obj2 = { a: 'name', b: 'age', c: 'movie' };
            let newArr = [];
            arr.forEach((item, index) => {
                let tempObj = {};
                for (let i in item) {
                    tempObj[obj2[i]] = item[i];
                }
                newArr.push(tempObj);
            });
            return newArr;
        }

        console.log(transformObj(arr));
    </script>
</body>
</html>