前端面试每日3+2(第37天)

1/8/2020 前端100问

当你发现自己的才华撑不起你的野心时,就请安静下来学习吧!

鲁迅说过:答案仅供参考...

# 1、第 51 题:Vue 的响应式原理中 Object.defineProperty 有什么缺陷?

为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?


🌿【解析】🌿

  1. Object.defineProperty无法监控数组下标的变化,导致通过数组下标添加元素,不能实时相应
  2. 数据的变化是通过getter/setter来追踪的。因为这种追踪方式,有些语法中,即便是数据发生了变化,vue也检查不到。比如 向Object添加属性/ 删除Object的属性。
  3. Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行便利,如果属性值是对象,还需要深度便利。Proxy可以劫持整个对象,并返回一个新的对象。
  4. Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。

抱歉,学会 Proxy 真的可以为所欲为 (opens new window)

参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)

# 2、第 52 题:怎么让一个 div 水平垂直居中


🌿【解析】🌿

<div class="parent">
  <div class="child"></div>
</div>
1
2
3

1.flex布局

div.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}
1
2
3
4
5
  1. 子元素定位
div.parent {
    position: relative; 
}

/* 子元素 定位 + 百分百 + transform移动调整 */
div.child {
    position: absolute; 
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);  
}
/* 或者 */
/* 子元素 定位 + 百分百 + margin移动调整 */

div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -25px;
    margin-top: -5px;
}
/* 或 */
/* 子元素 定位 + margin:auto */
div.child {
    width: 50px;
    height: 10px;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  1. grid布局
div.parent {
    display: grid;
}
div.child {
    justify-self: center;
    align-self: center;
}
1
2
3
4
5
6
7
  1. 利用inline-block的vertical-align对齐
div.parent {
    font-size: 0;
    text-align: center;
    &::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
}
div.child{
  display: inline-block;
  vertical-align: middle;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)

# 第 53 题:输出以下代码的执行结果并解释为什么?

var a = {n: 1};
var b = a;
a.x = a = {n: 2};

console.log(a.x) 	
console.log(b.x)
1
2
3
4
5
6

🌿【解析】🌿
结果:

undefined
{n:2}

首先,a和b同时引用了{n:2}对象,接着执行到a.x = a = {n:2}语句,尽管赋值是从右到左的没错,但是.的优先级比=要高,所以这里首先执行a.x,相当于为a(或者b)所指向的{n:1}对象新增了一个属性x,即此时对象将变为{n:1;x:undefined}。之后按正常情况,从右到左进行赋值,此时执行a ={n:2}的时候,a的引用改变,指向了新对象{n:2},而b依然指向的是旧对象。之后执行a.x = {n:2}的时候,并不会重新🌿【解析】🌿 一遍a,而是沿用最初🌿【解析】🌿 a.x时候的a,也即旧对象,故此时旧对象的x的值为{n:2},旧对象为 {n:1;x:{n:2}},它被b引用着。
后面输出a.x的时候,又要🌿【解析】🌿 a了,此时的a是指向新对象的a,而这个新对象是没有x属性的,故访问时输出undefined;而访问b.x的时候,将输出旧对象的x的值,即{n:2}。

参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)

# 4、第 54 题:冒泡排序如何实现,时间复杂度是多少, 还可以如何改进?


🌿【解析】🌿

function bubbleSort(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                const temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    console.log(arr);
}

// 改进冒泡排序
function bubbleSort1(arr) {
    let i = arr.length - 1;

    while (i > 0) {
        let pos = 0;
        for (let j = 0; j < i; j++) {
            if (arr[j] > arr[j + 1]) {
                pos = j;
                const temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        i = pos;
    }
    console.log(arr);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)

# 5、第 55 题:某公司 1 到 12 月份的销售额存在一个对象里面

如下:{1:222, 2:123, 5:888},请把数据处理为如下结构:[222, 123, null, null, 888, null, null, null, null, null, null, null]
1

🌿【解析】🌿 方法1

function arrToObject(obj) {
    let arr = [];
    for (let i = 0; i < 12; i++) {
        arr.push(null)
        for (let key in obj) {
            if(key == (i+1)){
                arr.splice(i, 1, obj[key])
            }
        }
    }
    return arr;
};
let obj = {1:222, 2:123, 5:888};

1
2
3
4
5
6
7
8
9
10
11
12
13
14

方法2

let obj = {1:222, 2:123, 5:888};
const result = Array.from({ length: 12 }).map((_, index) => obj[index + 1] || null);
console.log(result)
1
2
3

方法3

let data = { 1:222, 2:123, 5:888 }
const arr = new Array(12).fill(null).map((item, i) => data[i + 1] || item)
console.log('arr---------', arr)
1
2
3

参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)

Last Updated: 1/29/2020, 9:58:38 PM
    asphyxia
    逆时针向