尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

JavaScript核心知识体系与面试准备全攻略

JavaScript核心知识体系与面试准备全攻略 1. JavaScript 核心知识体系与面试准备指南作为一名经历过数十场技术面试的前端工程师我深知JavaScript基础知识在面试中的重要性。很多看似简单的概念在实际工作中却经常成为性能瓶颈和bug源头。本文将系统梳理JavaScript的核心知识体系帮助开发者建立完整的知识框架同时针对面试场景提供深度解析。JavaScript作为一门灵活多变的语言其核心机制往往隐藏在简单的语法背后。理解这些机制不仅能让你在面试中游刃有余更能提升日常开发中的问题解决能力。我们将从基础数据类型开始逐步深入到异步编程等高级主题每个部分都会结合实际面试题进行剖析。2. 基础数据类型与类型判断2.1 JavaScript的71种数据类型JavaScript中的数据类型可以分为两大类原始类型和对象类型。具体包括原始类型Undefined、Null、Boolean、Number、BigInt、String、Symbol对象类型Object包括Array、Function等特殊对象注意typeof null会返回object这是JavaScript早期实现的一个著名bug由于兼容性原因一直保留至今2.2 类型判断的四种方法typeof操作符typeof 42 // number typeof hello // string typeof undefined // undefined typeof true // boolean typeof Symbol() // symbol typeof {} // object typeof [] // object (注意数组也是object) typeof function(){} // functioninstanceof操作符 用于检测构造函数的prototype属性是否出现在对象的原型链上[] instanceof Array // true new Date() instanceof Date // trueObject.prototype.toString 最可靠的类型判断方法Object.prototype.toString.call([]) // [object Array] Object.prototype.toString.call(null) // [object Null]Array.isArray() 专门用于判断数组类型Array.isArray([]) // true Array.isArray({}) // false2.3 类型转换的陷阱面试中经常考察和的区别1 1 // true (类型转换后比较) 1 1 // false (严格比较不转换类型) 0 false // true 0 false // false null undefined // true null undefined // false3. 变量、作用域与闭包3.1 var、let和const的区别特性varletconst作用域函数作用域块级作用域块级作用域变量提升是否否重复声明允许不允许不允许初始值可不设可不设必须设置重新赋值允许允许不允许3.2 作用域链与闭包闭包是指有权访问另一个函数作用域中的变量的函数。理解闭包需要掌握词法作用域函数在定义时就确定了作用域而非执行时执行上下文包含变量对象、作用域链和this值垃圾回收闭包会阻止被引用的变量被回收经典面试题for(var i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); } // 输出五个5如何修改使其输出0-4解决方案// 使用let for(let i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); } // 或使用IIFE for(var i 0; i 5; i) { (function(j) { setTimeout(function() { console.log(j); }, 1000); })(i); }4. 数组操作与性能考量4.1 数组方法分类变异方法会改变原数组push/pop/shift/unshiftsplice/sort/reversefill/copyWithin非变异方法返回新数组slice/concatmap/filter/reduceflat/flatMap4.2 数组遍历性能对比方法速度可中断适用场景for循环最快是需要高性能的场景forEach中等否简单遍历for...of慢是需要可读性的场景map/filter慢否需要返回新数组的场景4.3 数组去重的几种方式// 使用Set const unique arr [...new Set(arr)]; // 使用filter const unique arr arr.filter((item, index) arr.indexOf(item) index); // 使用reduce const unique arr arr.reduce((acc, cur) acc.includes(cur) ? acc : [...acc, cur], []);5. 函数进阶与this指向5.1 箭头函数与普通函数区别特性普通函数箭头函数this绑定动态绑定词法绑定arguments有无构造函数可以不可以prototype有无yield可用不可用5.2 this指向的四种规则默认绑定非严格模式下指向window严格模式为undefined隐式绑定作为对象方法调用时指向该对象显式绑定通过call/apply/bind指定thisnew绑定构造函数中的this指向新创建的对象5.3 手写call/apply/bind// call实现 Function.prototype.myCall function(context, ...args) { context context || window; const fn Symbol(); context[fn] this; const result context[fn](...args); delete context[fn]; return result; }; // bind实现 Function.prototype.myBind function(context, ...args) { const self this; return function(...innerArgs) { return self.apply(context, args.concat(innerArgs)); }; };6. 对象与原型系统6.1 原型链示意图实例对象.__proto__ → 构造函数.prototype → Object.prototype → null6.2 继承的几种方式原型链继承function Parent() {} function Child() {} Child.prototype new Parent();构造函数继承function Child() { Parent.call(this); }组合继承最常用function Child() { Parent.call(this); } Child.prototype Object.create(Parent.prototype); Child.prototype.constructor Child;ES6 class继承class Child extends Parent { constructor() { super(); } }6.3 深拷贝的实现function deepClone(obj, map new WeakMap()) { if (obj null || typeof obj ! object) return obj; if (map.has(obj)) return map.get(obj); const clone Array.isArray(obj) ? [] : {}; map.set(obj, clone); for (const key in obj) { if (obj.hasOwnProperty(key)) { clone[key] deepClone(obj[key], map); } } return clone; }7. 异步编程模型7.1 事件循环机制JavaScript的事件循环执行顺序执行同步代码执行所有微任务Promise.then, process.nextTick执行一个宏任务setTimeout, setInterval, I/O重复2-3步骤7.2 Promise核心实现class MyPromise { constructor(executor) { this.state pending; this.value undefined; this.reason undefined; this.onFulfilledCallbacks []; this.onRejectedCallbacks []; const resolve value { if (this.state pending) { this.state fulfilled; this.value value; this.onFulfilledCallbacks.forEach(fn fn()); } }; const reject reason { if (this.state pending) { this.state rejected; this.reason reason; this.onRejectedCallbacks.forEach(fn fn()); } }; try { executor(resolve, reject); } catch (err) { reject(err); } } then(onFulfilled, onRejected) { return new MyPromise((resolve, reject) { const handleFulfilled () { try { const x onFulfilled(this.value); x instanceof MyPromise ? x.then(resolve, reject) : resolve(x); } catch (err) { reject(err); } }; const handleRejected () { try { const x onRejected(this.reason); x instanceof MyPromise ? x.then(resolve, reject) : resolve(x); } catch (err) { reject(err); } }; if (this.state fulfilled) { handleFulfilled(); } else if (this.state rejected) { handleRejected(); } else { this.onFulfilledCallbacks.push(handleFulfilled); this.onRejectedCallbacks.push(handleRejected); } }); } }7.3 async/await原理async函数本质上是Generator函数的语法糖其执行过程遇到await时会暂停async函数的执行等待Promise解决后继续执行async函数如果Promise被拒绝会抛出异常// async/await转换为Promise形式 async function example() { const result await somePromise(); return result 1; } // 等价于 function example() { return somePromise().then(result { return result 1; }); }8. 面试实战技巧与高频问题8.1 高频面试问题整理闭包应用场景模块模式函数柯里化记忆化函数事件处理回调原型链相关问题如何实现继承instanceof原理是什么new操作符做了什么异步编程问题事件循环执行顺序Promise.all/Promise.race实现如何取消Promise8.2 代码输出题解析console.log(1); setTimeout(() { console.log(2); Promise.resolve().then(() console.log(3)); }, 0); new Promise((resolve) { console.log(4); resolve(); }).then(() { console.log(5); setTimeout(() console.log(6), 0); }); console.log(7); // 输出顺序1, 4, 7, 5, 2, 3, 68.3 手写代码准备清单实现Promise及相关静态方法实现call/apply/bind实现深拷贝实现防抖节流实现观察者模式实现数组扁平化实现函数柯里化在实际面试中理解概念背后的原理比死记硬背更重要。建议对每个知识点都尝试自己实现一遍遇到问题时多思考为什么这样设计。JavaScript的很多特性都有其历史原因和实际考量理解这些背景能让你在面试中给出更有深度的回答。
返回列表