【前端面试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 });

#总结

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

相关推荐
LJianK12 小时前
BUG: Uncaught Error: [DecimalError] Invalid argument: .0
前端
No Silver Bullet2 小时前
Nginx 内存不足对Web 应用的影响分析
运维·前端·nginx
一起养小猫2 小时前
Flutter for OpenHarmony 实战 表单处理与验证完整指南
android·开发语言·前端·javascript·flutter·harmonyos
weixin_395448913 小时前
main.c_cursor_0130
前端·网络·算法
C澒3 小时前
SGW 接入层运维实战:配置查看 + 监控分析 + 日志排查
前端·安全·运维开发
德育处主任Pro3 小时前
『NAS』在群晖部署一款太空策略游戏-ogame-vue-ts
前端·vue.js·游戏
ziqi5224 小时前
第二十五天笔记
前端·chrome·笔记
GISer_Jing4 小时前
Memory、Rules、Skills、MCP如何重塑AI编程
前端·人工智能·aigc·ai编程
xcs194054 小时前
前端 项目构建问题 \node_modules\loader-runner\lib\loadLoader.js
开发语言·前端·javascript