常见面试问题
自适应布局中的 rem 是什么原理?
rem(root em)是css中一种相对长度单位,其核心原理是相对于跟元素(html)的字体大小进行缩放。
核心原理
rem的基准是根元素HTML的font-size属性:
| 1 | html{ | 
动态计算
所有使用rem的元素尺寸都会根据字体大小动态计算:
| 1 | .demo{ | 
自适应关键
通过JS或媒体查询动态修改根字体大小,页面所有rem单位元素都会等比例缩放:
| 1 | //根据视口宽度动态设置根元素字体大小 | 
工作流程
1. 设计稿基准
假设设计稿宽度750px,约定1rem = 设计稿100px
2. 设计根字体
| 1 | // 视口宽度375px的设备上: | 
3. 元素尺寸转换
| 1 | /* 设计稿中200px宽的元素 */ | 
4. 不同屏幕效果
| 设备宽度 | 跟字体大小 | 元素实际宽度 | 
|---|---|---|
| 375px | 50px | 2X50=100px | 
对比其他单位
| 单位 | 基准 | 自适应能力 | 缺点 | 
|---|---|---|---|
| rem | 根元素字体大小 | 🌟🌟🌟🌟🌟 | 需要动态计算根字体 | 
| em | 父元素字体大小 | 🌟🌟 | 嵌套层级影响计算 | 
| px | 固定像素 | 无法自适应 | |
| vw | 视口宽度的1% | 🌟🌟🌟🌟 | 小屏幕显示内容可能过小 | 
| % | 父元素尺寸的百分比 | 🌟🌟🌟 | 依赖父级容器 | 
对于CSS中盒模型的理解
盒模型是CSS布局中的核心概念,它描述了HTML元素在页面所占空间结构。每个元素都被视作一个矩形盒子。这个盒子包含以下四个部分:
- 内容区(content):- 最内层区域,包含元素的实际内容(如文本、图片等)。
- 大小由width和height属性控制。
 
- 内边距(padding):- 位于内容区和边框之间的透明区域。
- 控制内容与边框之间的距离。
- 大小由padding及其相关属性(padding-left、padding-right、padding-top、padding-bottom)控制。
 
- 边框(border):- 包裹内容和内边距的
- 可以设置颜色,粗细,样式。
- 大小由border相关属性控制
 
- 外边距(margin):- 位于边框之外的透明区域。
- 控制当前元素与其他元素之间的距离。
- 大小由margin相关属性控制。
 
关键点:
- 总高度/宽度计算:- 总宽度 = width+ 左(padding、margin、border)+ 右(padding、margin、border)
- 总高度 = height+ 上(padding、margin、border)+ 下(padding、margin、border)
 
- 总宽度 = 
- box
- box-sizing属性:这个属性决定了- width和- height属性具体定义的是哪一部分的尺寸。这里是理解盒模型的关键差异点:- content-box:默认(标准)盒模型:- width和- height只定义内容区的尺寸。
- 元素的总宽度/高度需要加上padding,border,margin。
 
- border-box常用(IE怪异/现代推荐)盒模型:- width和- height定义了 内容区 + 内边距 + 边框 的总尺寸。
- 元素的总宽度/高度 = width/height + margin。 padding 和 border 的宽度被包含在设定的 width/height 值内。
- 这使得布局计算更直观,是现在最常用的设置(通常用 * { box-sizing: border-box; } 全局设置)。
 
 
- 外边距折叠(Margin Collapsing): 垂直方向上相邻的两个块级元素的外边距有时会合并(折叠)成一个外边距,其大小等于两个外边距中的较大者。
总结:
盒模型是理解元素尺寸、间距和布局的基础。掌握内容区、内边距、边框、外边距的定义,以及 box-sizing 属性(尤其是 border-box)对元素最终尺寸的影响,对于精确控制页面布局至关重要。外边距折叠是另一个需要注意的特性,特别是在垂直布局时。
什么是变量提升?var、let、const有什么区别?
- var:声明被提升到顶部,初始值为- undefined.- 1 
 2- console.log(e) //undefined 
 var e = 1;
- let和- const存在暂时性死区,在声明前访问会报错。- 1 
 2- console.log(e) // RefrenceError 
 let e = 10;
如何确定this指向
- 普通函数:this指向调用者。
- 箭头函数:this继承外部作用域。
- 显示绑定:call、apply、bind1 
 2
 3const obj = { name: "Alice" }; 
 function greet() { console.log(this.name); }
 greet.call(obj); // "Alice"
解释事件循环、宏任务与微任务。
- 调用栈:同步代码执行。
- 任务队列:- 宏任务:setTimeout、setinterval、I/O。
- 微任务:Promise.then、MutationObserver、queueMicrotask
- 执行顺序:同步代码 → 微任务队列清空 → 宏任务。
 
- 宏任务:
Promise 如何解决回调地狱?async/await 的作用?
- Promise链式调用:- 1 
 2
 3
 4- fetch(url) 
 .then(res => res.json())
 .then(data => console.log(data))
 .catch(err => console.error(err));
- async/await以同步的方式写异步代码。- 1 
 2
 3
 4
 5
 6
 7
 8- async function getData(){ 
 try {
 const res = await fetch(url);
 const data = await res.json();
 } catch (err) {
 console.error(err);
 }
 }
列举常用的 ES6 特性。
- let/const、箭头函数、解构赋值。
- 模板字符串、默认参数、Rest/Spread 运算符。
- 模块化(import/export)、类(class)、Map/Set。
防抖和截流区别是什么?如何实现?
- 防抖:连续触发时,只执行最后一次。1 
 2
 3
 4
 5
 6
 7function debounce(fn, delay) { 
 let timer;
 return (...args) => {
 clearTimeout(timer);
 timer = setTimeout(() => fn(...args), delay);
 };
 }
- 节流:固定时间间隔执行一次(如滚动事件)。1 
 2
 3
 4
 5
 6
 7
 8
 9
 10function throttle(fn, interval) { 
 let lastTime = 0;
 return (...args) => {
 const now = Date.now();
 if (now - lastTime >= interval) {
 fn(...args);
 lastTime = now;
 }
 };
 }
如何解决跨域问题
- CORS:服务器设置响应头(Access-Control-Allow-Origin)。
- JSONP:通过 <script>标签跨域(仅 GET 请求)。
- 代理服务器:前端请求同域代理,代理转发请求。
- WebSocket:不受同源策略限制。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 CCの日记!
 评论
