2020-07-07 08:23:56
答案概述:此次美团到家秋招前端一面主要考察了前端基础知识(CSS、JS)、ES6特性、作用域与闭包、原型链、异步编程及算法能力,部分八股文因长期未复习导致卡顿,但算法表现较好,已通过一面并约二面。以下为具体问题解析:
一、CSS 相关flex 常用属性
display: flex:启用弹性布局。
justify-content:主轴对齐方式(如 flex-start、center、space-between)。
align-items:交叉轴对齐方式(如 stretch、center)。
flex-direction:主轴方向(row 或 column)。
flex-wrap:是否换行(nowrap、wrap)。
position 定位
fixed:相对于视口定位,脱离文档流。
relative:相对于自身原位置偏移,不脱离文档流。
flex:1 的三个值
flex: 1 是 flex-grow: 1、flex-shrink: 1、flex-basis: 0% 的简写。
最后一个属性为 0 表示初始宽度为 0,剩余空间按比例分配。
盒模型
标准盒模型(content-box):宽高仅包含内容,padding 和 border 会额外增加元素尺寸。
IE 盒模型(border-box):宽高包含内容、padding 和 border,设置 width:100px 时手察总宽度固定为 100px。
设置方式:box-sizing: content-box | border-box。
不定宽高水平垂直居中
Flex 方案:父容器设置 display: flex; justify-content: center; align-items: center。
Grid 方案:父容器设置 display: grid; place-items: center。
绝对定位 + transform:子元素 position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)。
ES6 常用语法
let/const:块级作用域变量声明。
箭头函数:简化函数写法,无独立 this。
模板字符串:反引号 ` 支持多行字符串和变量笑薯裂插值。
解构赋值:const {a, b} = obj。
模块化:import/export。
let/const 的设计原因
解决 var 的变量提升和作用域污染问题(如循环中的闭包陷阱)。
const 强制常量不可变,提升代码可读性。
setTimeout 输出问题
题目:var i = 0; setTimeout(() => console.log(i), 100); i = 123; 输出 123。
原因:var 是函数作用域,setTimeout 回调共享同一 i,最终值为 123。
修复:用 let(块级作用域)或闭包保存每次循环的 i。
闭包与数据清理
概念:闭包是函数能访问其定义时的词法作用域,即使函数在其词法作用域之外执行。
项目应用:如事件监听器中移除监听时需清理闭包引用的变量,避免内存泄漏。
JS 垃圾回收
标记清除:标记不可达对象并回收。
引用计数:引用计数为 0 时回收(但循环引用会导致泄漏)。
数碰闭据类型辨别
typeof:区分原始类型(如 number、string),但 null 返回 object,函数返回 function。
instanceof:检测对象是否为某构造函数的实例(基于原型链)。
Object.prototype.toString.call():通用方法,返回 [object Type]。
instanceof 原理
遍历原型链,检查对象的 __proto__ 是否等于构造函数的 prototype。
手动实现:
function myInstanceof(obj, constructor) { while (obj != null) { if (obj.__proto__ === constructor.prototype) return true; obj = obj.__proto__; } return false;}原型与原型链
构造函数:通过 new 创建实例,如 function Person() {}。
实例:const p = new Person(),p.__proto__ === Person.prototype。
原型链:实例通过 __proto__ 向上查找属性,直到 Object.prototype.__proto__ === null。
手写 new
function myNew(constructor, ...args) { const obj = Object.create(constructor.prototype); const result = constructor.apply(obj, args); return result instanceof Object ? result : obj;}Object.create 参数
传入一个原型对象(如 Object.create(null) 创建无原型对象)。
箭头函数设计原因
简化函数写法,解决 this 指向问题(箭头函数无独立 this,继承外层作用域的 this)。
构造函数使用条件
必须用 new 调用,否则 this 指向全局对象(严格模式为 undefined)。
改变 this 指向
call/apply/bind:显式绑定 this。
箭头函数:继承外层 this。
输出题:obj.a() 与 (obj.a)()
若 obj.a 是普通函数,两者输出相同(this 指向 obj)。
若 obj.a 返回箭头函数,obj.a() 的 this 可能丢失(取决于箭头函数定义位置)。
事件循环
宏任务:setTimeout、setInterval、I/O。
微任务:Promise.then、MutationObserver。
执行顺序:同步代码 → 微任务 → 宏任务。
事件循环输出题(async/await)
示例:
async function foo() { console.log(1); await Promise.resolve(); console.log(2);}foo();console.log(3);// 输出:1 → 3 → 2(await 将后续代码推入微任务队列)导入:使用库如 xlsx 解析文件,转换为 JSON 数据后处理。
导出:将数据转换为 Excel 格式(如 SheetJS 生成二进制文件下载)。