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

1/9/2020 前端100问

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

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

# 1、第 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

🌿【解析】🌿
自己写了一版本,为了实现而实现的,认真脸:

function LazyMan(name) {
  return new function () {
    this.name = name
    console.log(`Hi I am ${this.name}`)
    this.events = []
    this.firstEvents = []
    this.eat = function (el) {
      this.events.push(() => console.log(`I am eating ${el}`))
      return this
    }
    this.sleepFirst = function(time){
      this.firstEvents = this.events.map((event)=>event)
      this.events = []
      setTimeout(()=>{
        time != 0 ? console.log(`等待了${time}秒...`) : null
        this.firstEvents.forEach(event => event())  
      },time * 1000)
      return this
    }
    this.sleep = function (time) {
      if(this.firstEvents==0) this.events = this.events.filter(event => event())  
      setTimeout(()=>{
        console.log(`等待了${time}秒...`)
        this.events.forEach(event => event())  
      },time * 1000)
      return this
    }

  }
}
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 dinner


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

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

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


🌿【解析】🌿

  1. display: none
    • 结构:不占空间,不能点击
    • 性能:导致回流,性能开销较大
    • 继承:非继承属性,渲染树消失,修改子孙大节点也无法显示
    • 场景
      • 显示出原来这里不存在的结构
  2. opacity: 0
    • 占据空间,可以点击
    • 重建图层,性能较高
    • 非继承属性,渲染树消失,修改子孙大节点也无法显示
    • 场景
      • 可以跟transition搭配
      • 自定义图片上传按钮
  3. visibility: hidden
    • 占据空间,不能点击
    • 导致重绘,性能稍好
    • 继承属性,设置子孙节点visibility: visible,让子孙节点显示
    • 场景:
      • 显示不会导致页面结构发生变动,不会撑开

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

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


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

  1. 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。
  2. 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  3. 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
  4. 不可以使用 new 命令,因为:
  • 没有自己的 this,无法调用 call,apply。
  • 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数的 prototype 赋值给新的对象的 proto
  • new 过程大致是这样的:
function newFunc(father, ...rest) {
  var result = {};
  result.__proto__ = father.prototype;
  var result2 = father.apply(result, rest);
  if (
    (typeof result2 === 'object' || typeof result2 === 'function') &&
    result2 !== null
  ) {
    return result2;
  }
  return result;
}
1
2
3
4
5
6
7
8
9
10
11
12

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

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

例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。


🌿【解析】🌿

// 1.
const intersect = (nums1, nums2) => {
  const map = {}
  const res = []
  for (let n of nums1) {
    if (map[n]) {
      map[n]++
    } else {
      map[n] = 1
    }
  }
  for (let n of nums2) {
    if (map[n] > 0) {
      res.push(n)
      map[n]--
    }
  }
  return res
}
// 空间换时间
const intersect = function (nums1, nums2) {
        let map = {},
            result = [];
        
        nums1.forEach(i => map[i] = ++ map[i] || 1);
        nums2.forEach(i => map[i] > 0 && (result.push(i), map[i] --));
        return result;
}
// 时间换空间
const intersect = function (nums1, nums2) {
        let result = [];

        nums1.forEach(i => {
            let index = nums2.indexOf(i);
            if (index > -1) {
                result.push(nums2.splice(index, 1)[0]);
            }
        })
        return result;
}
// 测试
let nums1 = [1, 2, 2, 1], 
    nums2 = [2, 2, 3, 4],
    nums3 = [1, 1],
    nums4 = [1];

console.log(intersect(nums1, nums2)); // [2, 2]
console.log(intersect(nums3, nums4)); // [1]
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

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

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

<img src="1.jpg" style="width:480px!important;”>
1

🌿【解析】🌿

第一反应缩放 总结一下吧:

  1. css方法 max-width:300px;覆盖其样式; transform: scale(0.625);按比例缩放图片;
  2. js方法 document.getElementsByTagName("img")[0].setAttribute("style","width:300px!important;")

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

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