前端面试题 10 道题突破面试难关
2024-01-13 23:45:29
导言
前端工程师是互联网行业中炙手可热的角色,随着互联网的迅猛发展,前端工程师的需求量也与日俱增。想要成为一名合格的前端工程师,不仅需要扎实的基础知识,还需要不断学习和掌握新的技术。面试是前端工程师求职过程中不可避免的一环,也是考察候选人能力和潜力的重要环节。为了帮助广大前端工程师更好地备战面试,我们精心整理了 10 道前端面试题,涵盖算法、封装函数、数组处理、深度复制、Vue 生命周期、设计模式等热门话题,旨在帮助大家全面掌握前端开发核心技能,轻松征服面试官。
正文
1. 封装一个方法,要求把给定的任意的数组(不定长参数)去重,并返回新的数组。
// 实现方法
function unique(arr) {
return [...new Set(arr)];
}
// 测试用例
const arr = [1, 2, 3, 1, 2, 3, 4, 5, 6, 6, 7];
console.log(unique(arr)); // [1, 2, 3, 4, 5, 6, 7]
2. 封装一个方法,要求实现防抖功能。
// 实现方法
function debounce(func, wait) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
// 测试用例
const func = () => {
console.log('防抖成功');
};
const debouncedFunc = debounce(func, 500);
debouncedFunc(); // 500ms 内多次调用只会执行一次
3. 封装一个方法,要求实现节流功能。
// 实现方法
function throttle(func, wait) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime > wait) {
func.apply(this, args);
lastTime = now;
}
};
}
// 测试用例
const func = () => {
console.log('节流成功');
};
const throttledFunc = throttle(func, 500);
throttledFunc(); // 500ms 内多次调用只执行一次
4. 实现一个深拷贝函数,能够复制对象和数组的子元素。
// 实现方法
function deepCopy(obj) {
const result = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return result;
}
// 测试用例
const obj = {
name: '前端工程师',
age: 25,
skills: ['JavaScript', 'HTML', 'CSS'],
projects: [
{
name: '项目一',
description: '这是一个非常棒的项目',
},
{
name: '项目二',
description: '这是一个非常棒的项目',
},
],
};
const copyObj = deepCopy(obj);
copyObj.name = '后端工程师';
copyObj.projects[0].name = '项目一已更新';
console.log(obj); // { name: '前端工程师', age: 25, skills: [ 'JavaScript', 'HTML', 'CSS' ], projects: [ { name: '项目一', description: '这是一个非常棒的项目' }, { name: '项目二', description: '这是一个非常棒的项目' } ] }
console.log(copyObj); // { name: '后端工程师', age: 25, skills: [ 'JavaScript', 'HTML', 'CSS' ], projects: [ { name: '项目一已更新', description: '这是一个非常棒的项目' }, { name: '项目二', description: '这是一个非常棒的项目' } ] }
5. Vue 生命周期中都有哪些钩子函数,请分别说明其作用。
Vue 生命周期中共有 9 个钩子函数,分别是:
beforeCreate
:在实例初始化之后、数据观测 (data observer) 和事件/监听器 (event/watcher) 配置之前被调用。created
:在实例创建完成后被立即调用。在这一步,实例已完成以下的初始化:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可用。beforeMount
:在挂载开始之前被调用。相关的 render 函数首次被调用。mounted
:在挂载完成后被立即调用。在这一步,$el 已被新创建的 Vue 实例获取。beforeUpdate
:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。updated
:由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。beforeDestroy
:实例销毁之前调用。在这一步,实例仍然完全可用。destroyed
:实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑,所有的事件监听器会被移除,所有的子实例也会被销毁。errorCaptured
:当捕获一个来自子孙组件的错误时调用。此钩子函数可以返回 false 来阻止该错误继续向上传播。
6. MVC/MVP/MVVM 的区别和联系是什么?
MVC(Model-View-Controller)是一种设计模式,它将应用程序分为三个部分:模型(Model)、视图(View)和控制器(Controller)。模型负责处理数据,视图负责展示数据,控制器负责处理用户交互。
MVP(Model-View-Presenter)是一种设计模式,它将应用程序分为三个部分:模型(Model)、视图(View)和展示器(Presenter)。模型负责处理数据,视图负责展示数据,展示器负责将模型中的数据转换为视图可以理解的形式。
MVVM(Model-View-ViewModel)是一种设计模式,它将应用程序分为三个部分:模型(Model)、视图(View)和视图模型(ViewModel)。模型负责处理数据,视图负责展示数据,视图模型负责将模型中的数据转换为视图可以理解的形式,并处理用户交互。
MVC、MVP 和 MVVM 都是设计模式,它们都旨在将应用程序划分为不同的部分,以便于维护和扩展。它们的区别在于:
- MVC 中,控制器负责处理用户交互。而在 MVP 和 MVVM 中,展示器和视图模型分别负责处理用户交互。
- MVC 中,视图直接访问模型。而在 MVP 和 MVVM 中,视图通过展示器或视图模型访问模型。
- MVC 中,模型、视图和控制器是紧耦合的。而在 MVP 和 MVVM 中,模型、视图和展示器/视图模型是松耦合的。
MVC、MVP 和 MVVM 都是非常流行的设计模式,它们在不同的场景中都有着各自的优势。
总结
以上 10 道前端面试题涵盖了算法、封装函数、数组处理、深度复制、Vue 生命周期、设计模式等热门话题,旨在帮助广大前端工程师全面掌握前端开发核心技能,轻松征服面试官。在面试过程中,重要的是要保持冷静和自信,并清晰地表达自己的思路和解决方案。相信通过不断的努力和学习,大家都能在前端工程师的道路上取得成功。