【前端面试2】基础面试(杂项)

文章目录

  • 前言
    • [1. Flex 布局缩写](#1. Flex 布局缩写)
    • [2.CSS 居中方案](#2.CSS 居中方案)
    • [3.v-if 与 v-show 的真实性能差异](#3.v-if 与 v-show 的真实性能差异)
    • [4.nextTick 到底在等什么](#4.nextTick 到底在等什么)
    • [5.循环中的 Key](#5.循环中的 Key)
    • 6.跨域问题 (CORS)
    • [7.map 和 forEach 的本质区别](#7.map 和 forEach 的本质区别)
    • 8.promise.all
    • 9.数组排序陷阱
    • 10.箭头函数坑

前言

大家好,今天是冲击中级工程师第二天,让我们来完成今天的面试题打卡。

1. Flex 布局缩写

题目:我们经常写 flex: 1,请问它其实是哪三个属性的缩写?默认值分别是多少?

css 复制代码
.item {
  flex: 1;
}

解释:

flex: 1 是 flex-grow、flex-shrink、flex-basis 这三个属性的缩写。

flex-grow: 1 (如果有剩余空间,我放大)

flex-shrink: 1 (如果有空间不足,我缩小)

flex-basis: 0% (我的初始大小忽略不计,优先占满剩余)

避坑:如果不写 flex: 1,默认值其实是 0 1 auto(不放大,会缩小,看内容大小)。

重点是flex-basis,它决定了按比例分配,而不是内容大小

2.CSS 居中方案

题目:未知宽高的元素如何水平垂直居中?为什么现在推荐用 transform 而不是 margin-top: -50%?

css 复制代码
.center {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

解释:常规下还有flex居中,这里讲解绝对定位的居中,

margin-top 的百分比是相对于父元素宽度的(这是一个反直觉的坑),很难精准居中。

transform: translate 的百分比是相对于元素自身宽度的。

3.v-if 与 v-show 的真实性能差异

题目:什么时候用 v-if,什么时候用 v-show?如果我要做一个频繁切换的 Tab 标签页,选哪个?
答案:使用v-show,v-if是真实"条件渲染",他会销毁和重建内部事件监听器和组件(触发生命周期),初始化开销小,切换开销大;v-show只是改变了css的display属性(block和none切换),组件一直在dom中,初始化开销大,切换开销小。

4.nextTick 到底在等什么

题目:修改了数据,想拿到 DOM 最新的高度,直接获取拿不到,为什么要包一层 nextTick?
答案:vue的更新是异步的,当修改message.value = 'new'时,vue并没有去直接更新dom,而是开启一个队列,把这个修改记下来。等待同一事件结束后,再统一更新dom,所以这时有可能拿不到最新的结果。nextTick就是在说:等事件结束,dom刷新后再执行我的回调。

5.循环中的 Key

题目:v-for 循环列表时,为什么不能用 index(数组下标)作为 key?
答案:当发生插入,删除,逆序操作时,会出现下面的后果:

1.如果你用 index 做 key,数据的 index 变了,但 key 没变(还是 0, 1, 2...)。

2.Vue 的 Diff 算法会认为"这个组件没变",于是它会复用之前的 DOM 节点,只更新里面的文字。

3.如果列表里有 Input 输入框,你会发现删除了第二项,结果第三项的数据跑到了第二项的输入框里,产生严重的 Bug。

6.跨域问题 (CORS)

题目:前端发请求报 CORS 错误,作为前端工程师,除了让后端加 Header,你本地开发怎么解决?
答案:使用前端代理

跨域是浏览器的安全限制,服务器与服务器之间通信是没有跨域限制的。 在 Vue/React 项目配置 devServer.proxy,其实就是启动了一个 Node 中间层。你的浏览器发给本地 Node,本地 Node 转发给后端,巧妙绕过了浏览器的同源策略。

7.map 和 forEach 的本质区别

题目: 都能遍历数组,它们最大的区别是什么?能用 break 跳出 forEach 吗?
答案:返回值:map 返回一个新数组(适合数据格式转换);forEach 返回 undefined(适合单纯执行副作用)。都不能用 break 或 continue 跳出循环。只能用 try/catch 抛出异常强行停止,或者改用普通的 for...of 循环。

8.promise.all

问题:Promise.all([p1, p2, p3]),如果 p2 报错了,p1 和 p3 的结果还能拿到吗?怎么解决?
答案:如果不处理,确实会直接崩盘。 解决技巧:在传入 all 之前,给每个 Promise 接一个 .catch()"兜底"。代码示例如下:

js 复制代码
// 即使出错,也返回一个带有 status 的对象,保证 all 能走完
Promise.all([
  p1.catch(e => ({ status: 'fail', err: e })),
  p2.catch(e => ({ status: 'fail', err: e }))
]).then(results => {
  // 这里可以过滤出成功的和失败的
})

还有就是使用Promise.allSettled()

9.数组排序陷阱

题目:下面代码输出什么?

javascript 复制代码
const arr = [1, 10, 2, 21];
arr.sort();
console.log(arr);

输出:[ 1, 10, 2, 21 ]

解释:sort() 如果不传比较函数,默认会将数字转换成字符串,然后按照字符编码(Unicode)顺序排序。 因为字符串 "10" 的第一个字符 "1" 比 "2" 小,所以 "10" 排在 "2" 前面。 修正:arr.sort((a, b) => a - b)

10.箭头函数坑

题目:下面代码输出什么?

javascript 复制代码
const getObj = () => { a: 1 };
console.log(getObj());

输出:undefined

解释:大括号 {} 在箭头函数里,默认被认为是代码块(Function Body),而不是对象字面量。代码块里写 a: 1 只是一个标签语法(Label),并没有 return 任何东西。 修正:用圆括号包起来 const getObj = () => ({ a: 1 });

#总结

今天面试题就到这里,让我们每天学习几个题,一起成长。管他难易,获得成长就好。明天见。

相关推荐
天若有情67321 小时前
从 try-catch 回调到链式调用:一种更优雅的 async/await 错误处理方案
前端·异常处理·前端开发·async·异步·await·异步编程
ShenJLLL1 天前
vue部分知识点.
前端·javascript·vue.js·前端框架
恋猫de小郭1 天前
你是不是觉得 R8 很讨厌,但 Android 为什么选择 R8 ?也许你对 R8 还不够了解
android·前端·flutter
PineappleCoder1 天前
告别“幻影坦克”:手把手教你丝滑规避布局抖动,让页面渲染快如闪电!
前端·性能优化
武帝为此1 天前
【Shell变量替换与测试】
前端·chrome
CappuccinoRose1 天前
CSS 语法学习文档(十九)
前端·css·属性·flex·grid·学习资源·格式化上下文
雷电法拉珑1 天前
财务数据批量采集
linux·前端·python
We་ct1 天前
LeetCode 105. 从前序与中序遍历序列构造二叉树:题解与思路解析
前端·算法·leetcode·链表·typescript
前端 贾公子1 天前
深入理解 Vue3 的 v-model 及自定义指令的实现原理(下)
前端·html