前端常问面试题及答案

面试题 1:请解释什么是语义化 HTML,以及它的重要性。
答案要点:

是什么: 语义化 HTML 是指在 HTML 结构中,使用具有明确含义的标签来组织内容,而不是仅仅为了样式或布局目的使用通用的

或 。例如,使用
表示页眉,

举例说明一些常用的 HTML5 语义化标签及其用途。

标签是不是就没用了?什么时候用
? 如何确保你的 HTML 代码是语义化的? 面试题 2:请解释 CSS 盒模型(Box Model),以及标准盒模型和怪异盒模型的区别。 答案要点:

是什么: CSS 盒模型是 CSS 布局的基本概念,它把所有 HTML 元素都看作是一个个的“盒子”。每个盒子都由四个部分组成(从内到外):
内容区 (Content): 元素实际的内容,如文本、图片等。
内边距 (Padding): 内容区和边框之间的空白区域。
边框 (Border): 包裹内容和内边距的线条。
外边距 (Margin): 边框之外的空白区域,用于控制元素与其他元素之间的距离。
标准盒模型 (W3C 标准盒模型 / Content-box):
宽度计算: width 和 height 属性只包括内容区 (Content) 的大小。
总宽度 = width + padding (左 + 右) + border (左 + 右) + margin (左 + 右)。
这是现代浏览器默认采用的盒模型。
怪异盒模型 (IE 盒模型 / Border-box):
宽度计算: width 和 height 属性包括内容区、内边距 (Padding) 和边框 (Border) 的大小。
总宽度 = width + margin (左 + 右)。
这是 IE 浏览器在 IE6 之前默认采用的盒模型(在 Quirks 模式下)。
如何切换: 可以通过 CSS 的 box-sizing 属性来控制盒模型:
box-sizing: content-box; 对应标准盒模型。
box-sizing: border-box; 对应怪异盒模型。
在现代前端开发中,通常会使用 box-sizing: border-box;,因为它更符合直觉,布局计算更简单。
延伸思考/面试官可能追问:

margin 合并(塌陷)问题是什么?如何解决?
display: inline-block 的特点和应用场景?
如何使用 box-sizing 来简化布局计算?
面试题 3:请解释 JavaScript 中 var、let、const 的区别,以及在实际开发中如何选择。
答案要点:

var:

作用域: 函数作用域或全局作用域。没有块级作用域({} 代码块内声明的 var 变量会“泄露”到外部)。
变量提升 (Hoisting): 声明会被提升到作用域顶部,并默认初始化为 undefined。
重复声明与修改: 允许在同一作用域内重复声明同一个变量,且可以随时修改其值。
问题: 作用域规则模糊,可能导致变量覆盖、意外的变量共享等问题。
let:

作用域: 块级作用域。变量只在其声明的 {} 代码块内有效。
变量提升: 声明会被提升,但存在于**“暂时性死区” (Temporal Dead Zone, TDZ)**,在声明前不可访问,否则会抛出 ReferenceError。
重复声明与修改: 不允许在同一作用域内重复声明同一个变量,但可以修改其值。
优势: 解决了 var 的作用域问题和重复声明问题,使代码更可预测和安全。
const:

作用域: 块级作用域。
变量提升: 声明会被提升,但存在于**“暂时性死区” (TDZ)**,在声明前不可访问。
重复声明与修改: 不允许在同一作用域内重复声明,且不允许修改其值(即常量)。声明时必须进行初始化。
注意: 对于对象或数组等引用类型,const 保证的是变量指向的内存地址不变,而不是对象或数组内部的属性或元素不可变。你可以修改 const 对象的属性或 const 数组的元素。
优势: 明确表明变量是一个常量,不可修改,增加代码的可读性和健壮性。
在实际开发中如何选择:

优先使用 const: 这是现代 JavaScript 开发的最佳实践。如果一个变量的值在声明后不需要改变,就使用 const。
只有在明确需要修改变量值时才使用 let: 当你知道变量的值会随着程序执行而变化时,才使用 let。
避免使用 var: 在现代 JavaScript (ES6+) 开发中,由于 let 和 const 解决了 var 的许多问题,通常推荐不再使用 var。
延伸思考/面试官可能追问:

let 和 const 如何解决了 var 在 for 循环中导致的问题?
解释“暂时性死区” (TDZ)。
const 声明的对象/数组内部属性是否可变?为什么?
面试题 4:解释 JavaScript 中的闭包(Closure)是什么?它有什么用途?可能导致什么问题?
答案要点:

是什么: 闭包是一个函数,它记住了自己被创建时的环境。具体来说,当一个内部函数被定义在另一个外部函数里面,并且内部函数引用了外部函数的局部变量时,就形成了闭包。即使外部函数已经执行完毕,其执行环境被销毁,但由于闭包(内部函数)仍然引用着那个环境中的变量,所以这些变量不会被垃圾回收机制回收,会一直保存在内存中。
用途(为什么使用):
数据封装和私有化: 可以创建拥有私有变量和函数的模块,外部无法直接访问或修改这些私有变量,只能通过闭包内部暴露的方法来操作,实现了类似面向对象中的封装性。
维护状态: 在事件处理函数、异步回调函数或计时器中,闭包可以“记住”创建时的上下文状态,从而在稍后的执行中访问和使用这些状态。例如,在循环中为多个元素添加事件监听器,每个事件处理函数(闭包)可以访问到对应元素的正确信息。
创建工厂函数: 可以通过一个外部函数,返回一个或多个内部函数,这些内部函数共享或访问外部函数的变量,从而创建具有特定配置或状态的函数集合。
延迟执行和参数绑定: 可以用来延迟一个函数的执行,并在执行时保留某些参数。
可能导致的问题:
内存泄漏: 如果闭包长时间存在(比如一个事件监听器一直没有被移除),并且它持有对外部作用域中大量变量或 DOM 元素的引用,那么这些变量和 DOM 元素就无法被垃圾回收,可能导致内存占用持续增加。
循环中的陷阱(主要是 var 引起): 在使用 var 关键字的循环中创建闭包时,闭包会引用同一个外部变量(因为 var 没有块级作用域),导致所有闭包都记住的是循环结束时的最终变量值,而不是每次循环迭代时的值。这个问题在 let 和 const 出现后得到了解决。
延伸思考/面试官可能追问:

举例说明如何在前端项目中应用闭包(如计数器、模块模式、事件处理)。
如何避免闭包造成的内存泄漏?
闭包和作用域链的关系是什么?
总结:

这些问题都是前端面试中非常基础且核心的考察点。准备面试时,不仅要记住这些答案,更重要的是理解它们背后的原理、应用场景以及可能出现的问题。面试官往往会根据你的回答进行追问,以评估你对知识的深度和广度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谭俊杰Jerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值