一、前端JS基础(7道|生产高频踩坑)
1. 为什么简易深拷贝会丢失函数、Date、正则?如何写生产级完整深拷贝?
function deepClone(target, map = newWeakMap()) {// 基础类型直接返回if (target === null || typeof target !== 'object') return target;// 解决循环引用if (map.has(target)) return map.get(target);// 单独处理日期、正则if (target instanceof Date) return new Date(target);if (target instanceof RegExp) return new RegExp(target.source, target.flags);// 区分数组和对象const cloneTarget = Array.isArray(target) ? [] : {};map.set(target, cloneTarget);// 递归拷贝所有属性(包含不可枚举、Symbol属性)Reflect.ownKeys(target).forEach(key => {cloneTarget[key] = deepClone(target[key], map);});return cloneTarget;}// 业务测试用例const origin = {time: new Date(),reg: /\d+/g,fn: () => 123,list: [1, { a: 2 }]};const copy = deepClone(origin);
2. for...in 遍历数组为什么会多出属性、顺序错乱?业务遍历最佳方案?
// 经典踩坑案例Array.prototype.foo = 100;const arr = [1, 2, 3];for (let i in arr) {console.log(i); // 输出:0、1、2、foo(原型属性被遍历)}// 项目推荐写法for (const item of arr) {console.log(item);}
3. 防抖和节流的业务区别?滚动、搜索框如何精准选型?
// 防抖function debounce(fn, delay = 300) {let timer = null;return function (...args) {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};}// 节流function throttle(fn, interval = 200) {let lastTime = 0;return function (...args) {const now = Date.now();if (now - lastTime >= interval) {lastTime = now;fn.apply(this, args);}};}// 业务场景调用const searchHandle = debounce((val) => console.log('搜索', val), 500);window.addEventListener('scroll', throttle(() => console.log('滚动监听'), 200))
4. null 和 undefined 业务判空区别?为什么 typeof null 是 object?
// 统一判空工具function isEmpty(val) {return val === null || val === undefined;}// 接口字段兜底(只屏蔽null/undefined,0、''正常保留)const name = res.name ?? '默认名称';
5. 展开运算符是深拷贝还是浅拷贝?多层对象合并有什么坑?
const obj1 = { a: 1, info: { b: 2 } };const obj2 = { ...obj1 };obj2.info.b = 99;console.log(obj1.info.b); // 99 原数据被篡改!// 安全合并方案const safeObj = {...obj1,info: { ...obj1.info }};
6. Promise.all / race / allSettled 业务场景怎么选?
const reqList = [Promise.resolve(1), Promise.reject('失败'), Promise.resolve(3)];// 批量上报必备Promise.allSettled(reqList).then(res => {res.forEach(item => {item.status === 'fulfilled'? console.log('成功:', item.value): console.log('失败:', item.reason);});});
7. localStorage / sessionStorage / Cookie 线上业务选型?
二、Vue3 生产实战(6道|高频优化+踩坑)
8. reactive 解构丢失响应式,除了 toRefs 还有哪些解决方案?
import { reactive, toRef, toRefs } from 'vue';const state = reactive({ name: 'Vue', count: 0 });const name = toRef(state, 'name');const { count } = toRefs(state);
9. v-if 和 v-show 如何选型?大屏列表切换卡顿怎么优化?
<KeepAlive><component :is="currentComp"></component></KeepAlive>
10. Vue2 和 Vue3 v-model 核心区别?如何封装多字段双向绑定?
<!-- 子组件 --><template><input:value="name" @input="$emit('update:name', $event.target.value)" /><input:value="age" @input="$emit('update:age', $event.target.value)" /></template><scriptsetup>defineProps(['name', 'age'])defineEmits(['update:name', 'update:age'])</script><!-- 父组件使用 --><FormItemv-model:name="form.name"v-model:age="form.age" />
11. watch 监听对象不触发?深度监听性能如何优化?
import { watch, reactive } from 'vue';const user = reactive({ info: { num: 1 } });// 高性能写法:精准监听watch(() => user.info.num, val => {console.log('数值变化:', val);});
12. Vue路由history模式线上刷新404?Nginx如何配置?
location / {root /xxx/dist;index index.html;try_files $uri $uri/ /index.html;}
13. 打包后静态资源404、样式错乱是什么原因?
export default defineConfig({base: './', // 解决二级目录资源404build: {assetsDir: 'static'}})
三、React 生产实战(4道|渲染优化核心)
14. React useState 批量更新规则?为什么定时器不批量更新?
const [count, setCount] = useState(0);// 合成事件:批量更新const handleClick = () => {setCount(c => c + 1);setCount(c => c + 1);};// 定时器:非批量更新const timerClick = () => {setTimeout(() => {setCount(c => c + 1);setCount(c => c + 1);}, 0);};
15. React 组件重复渲染原因及全套优化方案?
const list = useMemo(() => [1,2,3], []);const handleChange = useCallback(() => {}, []);
16. useEffect 依赖项缺失、循环依赖会引发什么问题?
17. React 如何实现 Vue 同款 v-model 双向绑定?
function Input({ value, onChange }) {return <inputvalue={value}onChange={e => onChange(e.target.value)} />;}// 使用function App() {const [val, setVal] = useState('');return <Inputvalue={val}onChange={setVal} />;}
四、TypeScript 业务实战(3道|类型安全)
18. interface 和 type 业务选型与核心区别?
// interface 声明合并interface User { name: string }interface User { age: number }// type 联合类型type Status = 'success' | 'error' | 'loading';
19. 如何用TS约束接口返回值?any和unknown怎么用?
interface ResData {code: number;data: { id: number; title: string };msg: string;}async function fetchData(): Promise<ResData> {const res = await fetch('/api/list');return res.json();}
20. TS泛型有什么用?手写通用泛型列表组件
import React from 'react';interface ListProps<T> {data: T[];renderItem: (item: T) => React.ReactNode;}function List<T>({ data, renderItem }: ListProps<T>) {return (<ul>{data.map((item, idx) => (<likey={idx}>{renderItem(item)}</li>))}</ul>);}// 业务使用const App = () => {const list = [{ id: 1, name: '张三' }, { id: 2, name: '李四' }];return <Listdata={list}renderItem={item => <span>{item.name}</span>} />;};
💡 写在最后
文章来源:
四季读书网
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至23467321@qq.com举报,一经查实,本站将立刻删除;如已特别标注为本站原创文章的,转载时请以链接形式注明文章出处,谢谢!