前端面试每日3+2(第37天)
当你发现自己的才华撑不起你的野心时,就请安静下来学习吧!
鲁迅说过:
答案仅供参考...
# 1、第 51 题:Vue 的响应式原理中 Object.defineProperty 有什么缺陷?
为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
🌿【解析】🌿
- Object.defineProperty无法监控数组下标的变化,导致通过数组下标添加元素,不能实时相应
- 数据的变化是通过getter/setter来追踪的。因为这种追踪方式,有些语法中,即便是数据发生了变化,vue也检查不到。比如 向Object添加属性/ 删除Object的属性。
- Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行便利,如果属性值是对象,还需要深度便利。Proxy可以劫持整个对象,并返回一个新的对象。
- 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>
2
3
1.flex布局
div.parent {
display: flex;
justify-content: center;
align-items: center;
}
2
3
4
5
- 子元素定位
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;
}
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
- grid布局
div.parent {
display: grid;
}
div.child {
justify-self: center;
align-self: center;
}
2
3
4
5
6
7
- 利用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;
}
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)
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);
}
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
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};
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)
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)
2
3
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)