# 前端面试题及答案汇总(五) 51-60

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

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

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

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

console.log(a.x); // undefined
console.log(b.x); // {n: 2}
1
2
3
4
5
6

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

function bubbleSort(arr) {
  if (!arr || arr.length === 0) {
    return null;
  }
  for (let i = 0, len = arr.length; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] > arr[j]) {
        let temp = arr[j];
        arr[j] = arr[i];
        arr[i] = temp;
      }
    }
  }
  return arr;
}
const arr = [1, 5, 2, 3, 8, 4, 7];
console.log(bubbleSort(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
32
33
34
35
36

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

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

let obj = { 1: 222, 2: 123, 5: 888 };
function transform(obj) {
  let res = new Array(12).fill(null);
  for (let key in obj) {
    res[key - 1] = obj[key];
  }
  return res;
}
console.log(transform(obj));
1
2
3
4
5
6
7
8
9

# 第 56 题:要求设计 LazyMan 类,实现以下功能。

LazyMan("Tony");
// Hi I am Tony

LazyMan("Tony")
  .sleep(10)
  .eat("lunch");
// Hi I am Tony
// 等待了10秒...
// I am eating lunch

LazyMan("Tony")
  .eat("lunch")
  .sleep(10)
  .eat("dinner");
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner

LazyMan("Tony")
  .eat("lunch")
  .eat("dinner")
  .sleepFirst(5)
  .sleep(10)
  .eat("junk food");
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
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
class LazyManClass {
  constructor(name) {
    this.taskList = [];
    console.log(`Hi I am ${name}`);
    setTimeout(() => {
      this.next();
    }, 0);
  }
  sleep(time) {
    const fn = () => {
      setTimeout(() => {
        this.next();
      }, time * 1000);
    };
    this.taskList.push(fn);
    return this;
  }
  eat(food) {
    const fn = () => {
      console.log(`I am eating ${food}`);
      this.next();
    };
    this.taskList.push(fn);
    return this;
  }
  sleepFirst(time) {
    const fn = () => {
      setTimeout(() => {
        this.next();
      }, time * 1000);
    };
    this.taskList.unshift(fn);
    return this;
  }
  next() {
    const fn = this.taskList.shift();
    fn && fn();
  }
}
function LazyMan(name) {
  return new LazyManClass(name);
}
LazyMan("Tony")
  .eat("lunch")
  .eat("dinner")
  .sleepFirst(2)
  .sleep(1)
  .eat("junk food");
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
37
38
39
40
41
42
43
44
45
46
47
48

# 第 57 题:分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景。

  • display: none;
  1. DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性能:动态改变此属性时会引起重排,性能较差;
  4. 继承:不会被子元素继承,毕竟子类也不会被渲染;
  5. transition:transition 不支持 display。
  • visibility: hidden;
  1. DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
  2. 事件监听:无法进行 DOM 事件监听;
  3. 性 能:动态改变此属性时会引起重绘,性能较高;
  4. 继 承:会被子元素继承,子元素可以通过设置 visibility: visible; 来取消隐藏;
  5. transition:visibility 会立即显示,隐藏时会延时
  • opacity: 0;
  1. DOM 结构:透明度为 100%,元素隐藏,占据空间;
  2. 事件监听:可以进行 DOM 事件监听;
  3. 性 能:提升为合成层,不会触发重绘,性能较高;
  4. 继 承:会被子元素继承,且,子元素并不能通过 opacity: 1 来取消隐藏;
  5. transition:opacity 可以延时显示和隐藏。

# 第 58 题:箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?

箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:

  1. 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。

  2. 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  3. 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。

  4. 没有 prototype 属性,即指向 undefined;

  5. 不可以使用 new 命令,因为:

JavaScript 函数两个内部方法: [[Call]]和[[Construct]]

直接调用时执行[[Call]]方法, 直接执行函数体

new 调用时执行[[Construct]]方法, 创建一个实例对象 blabla(如下)

# 第 59 题:给定两个数组,写一个方法来计算它们的交集。

function union(arr1, arr2) {
  if (!arr1 || !arr2 || arr1.length === 0 || arr2.length === 0) {
    return null;
  }
  let res = [];
  arr1.sort((a, b) => a - b);
  arr2.sort((a, b) => a - b);
  let p1 = 0;
  let p2 = 0;
  const len1 = arr1.length;
  const len2 = arr2.length;
  while (p1 < len1 && p2 < len2) {
    if (arr1[p1] === arr2[p2]) {
      res.push(arr1[p1]);
      p1++;
      p2++;
    } else if (arr1[p1] < arr2[p2]) {
      p1++;
    } else {
      p2++;
    }
  }
  return res;
}

const arr1 = [1, 2, 5, 3, 63, 42];
const arr2 = [42, 35, 1, 5, 111, 662, 77, 5];
console.log(union(arr1, arr2));
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

# 第 60 题:已知如下代码,如何修改才能让图片宽度为 300px ?注意下面代码不可修改。

  • max-width:300px
  • transform: scale(0.625);
  • box-sizing:border-box;
  • padding:90px;
  • zoom:0.625;