前端面试每日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
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
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 优劣和适用场景。
🌿【解析】🌿
- display: none
- 结构:不占空间,不能点击
- 性能:导致回流,性能开销较大
- 继承:非继承属性,渲染树消失,修改子孙大节点也无法显示
- 场景
- 显示出原来这里不存在的结构
- opacity: 0
- 占据空间,可以点击
- 重建图层,性能较高
- 非继承属性,渲染树消失,修改子孙大节点也无法显示
- 场景
- 可以跟transition搭配
- 自定义图片上传按钮
- visibility: hidden
- 占据空间,不能点击
- 导致重绘,性能稍好
- 继承属性,设置子孙节点
visibility: visible
,让子孙节点显示 - 场景:
- 显示不会导致页面结构发生变动,不会撑开
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)
# 3、第 58 题:箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?
🌿【解析】🌿
箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:
- 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。
- 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
- 不可以使用 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
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
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
🌿【解析】🌿
第一反应缩放 总结一下吧:
- css方法 max-width:300px;覆盖其样式; transform: scale(0.625);按比例缩放图片;
- js方法 document.getElementsByTagName("img")[0].setAttribute("style","width:300px!important;")
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)