被问爆的ES6面试题TOP10:从变量提升到Promise链式调用

发布时间:2026/7/17 13:29:20

被问爆的ES6面试题TOP10:从变量提升到Promise链式调用 被问爆的ES6面试题TOP10从变量提升到Promise链式调用在当今前端开发领域掌握ES6已成为求职者的基本门槛。各大互联网公司在技术面试中ES6相关问题的考察频率居高不下尤其注重候选人对新特性的理解深度与实际应用能力。本文将聚焦10个最具代表性的ES6面试题通过原理剖析、代码演示和常见误区解析帮助开发者构建系统化的知识体系。1. 变量声明三剑客let、const与var的本质区别变量声明方式是ES6基础中的基础也是面试官最爱深挖的起点。理解三者差异需要从作用域、提升行为和可变性三个维度切入。1.1 作用域与暂时性死区// var示例 function varTest() { console.log(foo); // undefined var foo bar; } // let示例 function letTest() { console.log(foo); // ReferenceError let foo bar; }关键差异点var函数作用域存在变量提升hoisting声明前访问得到undefinedlet/const块级作用域存在暂时性死区TDZ声明前访问抛错const必须在声明时初始化且不能重新赋值注意对象属性可修改注意const声明对象时限制的是变量绑定而非对象内容。使用Object.freeze()可实现完全不可变。1.2 实战中的选择策略声明方式适用场景典型用例const常量定义配置项、导入模块let变量更新循环计数器、状态变更var避免使用旧代码维护常见陷阱for循环中使用var会导致闭包问题。解决方案是改用let或使用IIFE// 问题代码 for (var i 0; i 3; i) { setTimeout(() console.log(i), 100); // 输出3个3 } // 解决方案1 for (let i 0; i 3; i) { setTimeout(() console.log(i), 100); // 0,1,2 } // 解决方案2 for (var i 0; i 3; i) { (function(j) { setTimeout(() console.log(j), 100); })(i); }2. 解构赋值的艺术与应用场景解构赋值绝非简单的语法糖它在现代前端代码中展现出强大的表达力。掌握其高级用法能让代码更简洁优雅。2.1 对象解构的进阶技巧// 嵌套解构 const user { id: 123, profile: { name: Alice, address: { city: Shanghai } } }; const { profile: { name, address: { city } } } user; // 重命名默认值 const { name: userName Guest } user.profile;实用场景函数参数解构替代options对象模块导入特定方法交换变量值无需临时变量2.2 数组解构的妙用// 跳过元素 const [first, , third] [a, b, c]; // 剩余运算符 const [head, ...tail] [1, 2, 3, 4]; // tail为[2,3,4] // 迭代器配合 function* fibs() { let a 0, b 1; while (true) { yield a; [a, b] [b, a b]; } } const [f0, f1, f2] fibs();3. 箭头函数的this绑定机制箭头函数的this行为是面试必考点需要结合执行上下文理论深入理解。3.1 this绑定原理const obj { name: Obj, regularFunc: function() { console.log(this.name); }, arrowFunc: () { console.log(this.name); // 指向外层this } }; obj.regularFunc(); // Obj obj.arrowFunc(); // undefined严格模式下关键特性继承自外层函数上下文词法作用域无法通过call/apply/bind修改不能用作构造函数无prototype属性3.2 适用场景对比推荐使用箭头函数回调函数避免thatthis套路需要保持this一致的场景如React事件处理器纯函数场景避免使用箭头函数对象方法定义需要动态this的场景如DOM事件监听原型方法定义4. 模板字符串的高级用法模板字符串远不止于字符串拼接它开启了字符串处理的新范式。4.1 标签模板实战function highlight(strings, ...values) { return strings.reduce((result, str, i) { return ${result}${str}mark${values[i] || }/mark; }, ); } const name Alice; const age 25; const html highlightHello ${name}, you are ${age}; // Hello markAlice/mark, you are mark25/mark应用场景国际化处理SQL查询构建XSS防护4.2 原始字符串访问const path String.rawC:\Development\project\index.html; console.log(path); // 保持原始反斜杠5. 扩展运算符的深层应用扩展运算符(...)是ES6最具革命性的操作符之一其应用远超数组展开。5.1 对象浅拷贝与合并// 对象浅拷贝 const original { a: 1, b: { c: 2 } }; const copy { ...original }; // 合并对象替代Object.assign const merged { ...obj1, ...obj2 }; // 默认值设置 const withDefaults { ...DEFAULTS, ...userConfig };5.2 函数参数处理// 替代arguments function logArgs(...args) { args.forEach(arg console.log(arg)); } // 必需参数剩余参数 function join(separator, ...values) { return values.join(separator); }6. Promise核心机制与手写实现Promise是异步编程的基石深入理解其实现原理至关重要。6.1 状态机与链式调用const promise new Promise((resolve, reject) { setTimeout(() resolve(done), 1000); }); promise .then(result { console.log(result); return result.toUpperCase(); }) .then(uppercased { console.log(uppercased); }) .catch(error { console.error(error); });关键点三种状态pending、fulfilled、rejectedthen方法返回新Promise错误冒泡机制6.2 手写Promise核心实现class MyPromise { constructor(executor) { this.state pending; this.value undefined; this.callbacks []; const resolve value { if (this.state ! pending) return; this.state fulfilled; this.value value; this.callbacks.forEach(cb cb.onFulfilled(value)); }; const reject reason { if (this.state ! pending) return; this.state rejected; this.value reason; this.callbacks.forEach(cb cb.onRejected(reason)); }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { return new MyPromise((resolve, reject) { const handleCallback () { try { const callback this.state fulfilled ? onFulfilled : onRejected; if (typeof callback ! function) { this.state fulfilled ? resolve(this.value) : reject(this.value); return; } const result callback(this.value); resolve(result); } catch (error) { reject(error); } }; if (this.state ! pending) { setTimeout(handleCallback, 0); } else { this.callbacks.push({ onFulfilled: () handleCallback(), onRejected: () handleCallback() }); } }); } }7. 迭代器协议与生成器函数理解迭代协议是掌握现代JavaScript异步编程的关键。7.1 可迭代协议实现const myIterable { [Symbol.iterator]: function* () { yield 1; yield 2; yield 3; } }; for (const value of myIterable) { console.log(value); // 1, 2, 3 }7.2 生成器控制异步流程function* fetchUserPosts(userId) { try { const user yield fetch(/users/${userId}); const posts yield fetch(/posts?userId${user.id}); return posts; } catch (error) { console.error(Failed:, error); } } // 执行器函数 function run(generator) { const iterator generator(); function iterate(iteration) { if (iteration.done) return iteration.value; const promise iteration.value; return promise.then( x iterate(iterator.next(x)), err iterate(iterator.throw(err)) ); } return iterate(iterator.next()); }8. Class语法与原型继承ES6的class本质上是语法糖但带来了更好的代码组织方式。8.1 继承实现对比// ES5继承 function Animal(name) { this.name name; } Animal.prototype.speak function() { console.log(this.name makes a noise.); }; function Dog(name) { Animal.call(this, name); } Dog.prototype Object.create(Animal.prototype); Dog.prototype.constructor Dog; // ES6继承 class Animal { constructor(name) { this.name name; } speak() { console.log(${this.name} makes a noise.); } } class Dog extends Animal { speak() { super.speak(); console.log(${this.name} barks.); } }8.2 静态方法与访问器class Logger { static instance null; static getInstance() { if (!Logger.instance) { Logger.instance new Logger(); } return Logger.instance; } constructor() { this.logs []; } get history() { return [...this.logs]; } set history(logs) { throw new Error(Cannot modify history directly); } }9. 模块化系统的演进与最佳实践ES6模块已成为现代前端开发的标配理解其特性至关重要。9.1 导出模式对比// 命名导出 export const PI 3.14; export function circleArea(r) { return PI * r * r; } // 默认导出 export default class Calculator { // ... } // 复合导出 export * from ./math; export { default as Calc } from ./calculator;9.2 动态导入与代码分割// 按需加载 button.addEventListener(click, async () { const module await import(./dialog.js); module.open(); }); // 预加载 const module await import(/* webpackPreload: true */ ./charting.js);10. Proxy与Reflect的元编程能力这些高级特性在框架开发中广泛应用展示了JavaScript的强大灵活性。10.1 数据绑定实现function reactive(target) { return new Proxy(target, { get(obj, key) { track(obj, key); return Reflect.get(obj, key); }, set(obj, key, value) { Reflect.set(obj, key, value); trigger(obj, key); return true; } }); } function track(target, key) { console.log(追踪: ${key}); } function trigger(target, key) { console.log(触发更新: ${key}); }10.2 属性验证代理const validator { set(target, key, value) { if (key age) { if (!Number.isInteger(value)) { throw new TypeError(Age must be an integer); } if (value 0) { throw new RangeError(Age must be positive); } } return Reflect.set(target, key, value); } }; const person new Proxy({}, validator); person.age 30; // 正常 person.age young; // 报错

相关新闻