版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JS经典面试题及详细答案(实战向)本次整理的面试题均为前端面试高频原题,覆盖JS基础、数据类型、作用域、闭包、原型、异步、ES6+、事件、防抖节流等核心考点,答案贴合工程实战,通俗易懂,无书面化套话。一、基础数据类型&运算考题1.JS有哪些数据类型?如何分类?答案:JS一共8种数据类型,分为基本数据类型和引用数据类型两大类。1)基本数据类型(值类型,存储在栈内存)Undefined、Null、Boolean、Number、String、Symbol、BigInt特点:赋值是值拷贝,相互赋值后互不影响,没有属性和方法(调用方法是包装类临时转换)。2)引用数据类型(存储在堆内存)Object(包含普通对象、数组、函数、正则、日期等)特点:变量存储的是内存地址,赋值是地址拷贝,多个变量指向同一个堆内存,修改会相互影响。2.null和undefined的区别?答案:1)undefined:表示变量已声明但未赋值,是系统默认的空值。常见场景:变量只声明不赋值、函数无返回值、对象不存在的属性、形参未传实参。2)null:表示手动设置的空对象,代表主动清空变量。常见场景:主动释放对象引用、初始化对象变量、接口返回空数据。3)核心区别:-typeofundefined==='undefined'-typeofnull==='object'(历史遗留bug,初代JS底层判定问题)-null==undefined为true,null===undefined为false3.0.1+0.2为什么不等于0.3?如何解决?答案:根本原因:JS数字采用IEEE754双精度浮点数存储,二进制无法精准表示部分十进制小数。0.1和0.2转换成二进制是无限循环小数,存储时会截断保留有限位数,相加后产生精度误差,结果为0.30000000000000004。解决方案:1)保留固定小数位:toFixed(n),适合展示场景(注意返回字符串,需转数字)2)放大整数计算后缩小:(0.1*10+0.2*10)/10,适合精准计算场景3)使用专业库:decimal.js、math.js,适合金融、支付等高精度场景4.==和===的区别?答案:1)==宽松相等:先转换数据类型,再比较值,存在隐式类型转换。转换规则:数字和字符串比较,字符串转数字;布尔值和其他类型比较,布尔转数字;null和undefined互相相等,不和其他值相等。2)===严格相等:先比较类型,再比较值,类型不同直接返回false,无类型转换。3)工作规范:日常开发优先使用===,避免隐式转换带来的诡异bug,仅在判断null/undefined时可用==(obj==null可同时判断空和未定义)。二、作用域&变量提升考题5.var、let、const的区别?答案:1)变量提升:var存在变量提升,声明前可访问,值为undefined;let、const无变量提升,声明前访问会报错(暂时性死区)。2)作用域:var只有全局作用域、函数作用域,无块级作用域;let、const支持块级作用域({}内部生效)。3)重复声明:var允许重复声明变量;let、const禁止重复声明。4)赋值修改:var、let是变量,可重复赋值修改;const是常量,必须初始化赋值,基础类型不可修改,引用类型可修改内部属性(仅禁止地址修改)。5)挂载全局:var声明的全局变量会挂载到window;let、const不会挂载到window。6.什么是暂时性死区?答案:在块级作用域中,从代码块开始到let/const变量声明之前的区域,就是该变量的暂时性死区。核心规则:变量在声明前无法访问、无法赋值,一旦访问直接报Cannotaccess'xxx'beforeinitialization错误。出现原因:let/const无变量提升,绑定当前块级作用域,不受外部变量影响,解决了var变量提升、全局污染的问题。7.什么是作用域链?答案:当代码执行时,当前作用域层层向上查找变量的链条,就是作用域链。查找规则:优先在当前作用域找,找不到就去父级作用域,一直找到全局作用域,全局找不到则报错。作用域链是闭包、变量查找、权限隔离的底层基础,函数的作用域在定义时确定,不是执行时确定。三、闭包核心考题(面试高频)8.什么是闭包?闭包的作用、优缺点?答案:闭包定义:内层函数引用了外层函数的变量/参数,外层函数执行结束后,内层函数依然可以访问外层变量,这种组合就是闭包。简单说:函数嵌套函数,内层访问外层变量,外层执行完毕变量不销毁。闭包作用:1)实现变量私有化,避免全局变量污染2)保留函数执行上下文,缓存变量状态3)实现柯里化、模块化、防抖节流等功能优点:隔离作用域、保存状态、封装私有变量缺点:外层函数变量无法被垃圾回收,容易造成内存泄漏;滥用会导致页面性能下降解决内存泄漏:使用完毕手动置空闭包函数变量=null9.经典闭包循环考题(带解析)题目:以下代码输出什么?如何改造输出0、1、2?PlainText
for(vari=0;i<3;i++){
setTimeout(()=>{
console.log(i)
},1000)
}答案解析:1)原代码输出:3、3、3原因:var无块级作用域,全局只有一个i;循环同步执行瞬间完成,i最终变为3;1秒后定时器执行,所有回调都读取同一个全局i,所以全部输出3。2)改造方案一(let块级作用域,最简):将var改为let,每次循环生成独立块级作用域,每个回调绑定独立i。3)改造方案二(闭包缓存):利用立即执行函数创建独立作用域,缓存每一次的i值。PlainText
for(vari=0;i<3;i++){
(function(j){
setTimeout(()=>{
console.log(j)
},1000)
})(i)
}四、原型&原型链考题10.原型、原型链的核心概念?答案:1)prototype(显式原型):每个构造函数都有的属性,是一个对象,用于存放实例共享的方法和属性,节省内存。2)__proto__(隐式原型):每个实例对象都有的属性,指向所属构造函数的prototype。3)原型链:实例的__proto__层层向上指向构造函数原型,最终指向Ototype,末端为null,这条链条就是原型链。属性查找规则:自身有属性则用自身,没有则顺着原型链向上查找,找到即返回,查到null返回undefined。11.constructor属性的作用?答案:每个原型对象都有constructor属性,指向对应的构造函数。作用:可以通过实例找到创建自己的构造函数,也可用于判断对象的类型。注意:手动修改prototype时,会丢失constructor指向,需要手动修复,否则类型判断会出错。12.instanceof原理?手动实现instanceof答案:原理:检测构造函数的prototype是否出现在某个实例对象的原型链上。手动实现:PlainText
functionmyInstanceof(obj,fn){
//遍历原型链
letproto=obj.__proto__
while(proto){
if(proto===totype)returntrue
proto=proto.__proto__
}
returnfalse
}五、this指向考题(重中之重)13.this的指向规则?(5种场景)答案:this指向调用时的上下文,和定义位置无关,5种核心场景:1)普通函数调用:this指向window(浏览器)/global(node),严格模式下为undefined2)对象方法调用:this指向调用方法的当前对象3)构造函数new调用:this指向new创建的实例对象4)bind/call/apply绑定:this指向手动绑定的第一个参数5)箭头函数:没有自己的this,继承外层作用域的this,且无法被bind/call/apply修改14.call、apply、bind的区别?答案:三者作用一致:手动修改函数this指向。1)call:立即执行函数,参数为逐个罗列(obj,p1,p2)2)apply:立即执行函数,参数为数组/伪数组(obj,[p1,p2])3)bind:不立即执行,返回一个修改好this的新函数,可延迟执行、多次调用六、异步JS考题15.同步、异步的区别?为什么需要异步?答案:1)同步:代码从上到下依次执行,上一行执行完才执行下一行,阻塞后续代码。适合简单逻辑,耗时操作会卡住页面。2)异步:耗时操作(定时器、接口请求、文件读取)交给浏览器后台执行,主线程继续往下走,不阻塞代码,耗时完成后再执行回调。3)异步意义:JS是单线程语言,异步机制解决了耗时操作阻塞页面渲染、交互卡顿的问题。16.宏任务和微任务的区别?事件循环执行顺序?答案:宏任务:耗时较长的任务,队列优先级低包含:script整体代码、setTimeout、setInterval、AJAX、DOM事件微任务:耗时极短的任务,队列优先级高包含:Promise.then/catch/finally、async/await后续代码、queueMicrotask事件循环执行顺序(必考):1)先执行同步代码2)清空所有微任务队列(全部执行完)3)执行一个宏任务4)重复2、3步骤,循环往复17.Promise的状态、优缺点?答案:Promise是异步解决方案,解决回调地狱问题。1)三种状态:-pending等待中(初始状态)-fulfilled成功(状态不可逆)-rejected失败(状态不可逆)2)特点:状态一旦改变,永久固定,不会二次变更;支持链式调用。3)优点:解决回调地狱、代码扁平化、统一异步错误处理、支持并行异步。4)缺点:无法取消Promise、错误需要手动捕获、pending状态无法监听进度。18.async/await的原理?和Promise的关系?答案:1)async/await是Promise的语法糖,底层依然是Promise,只是让异步代码看起来像同步代码。2)规则:-async修饰函数,返回值自动包装为Promise对象-await只能在async函数内使用,会阻塞当前代码,等待Promise执行完成-await等待成功状态,失败会报错,需要用try/catch捕获异常3)优势:彻底解决Promise链式调用的嵌套问题,代码可读性极高,是目前主流异步写法。七、数组&常用方法考题19.map、forEach、filter的区别?答案:1)forEach:单纯遍历数组,无返回值,不能中断遍历,适合单纯循环操作,不处理数据返回。2)map:遍历并返回新数组,支持数据加工转换,新数组长度和原数组一致,适合数据映射、字段转换。3)filter:遍历筛选数据,返回符合条件的新数组,新数组长度≤原数组,适合数据过滤。核心区别:forEach无返回;map加工数据;filter筛选数据。20.数组去重的常用方法?答案:1)ES6Set去重(最简,日常开发首选)PlainText
constarr=[...newSet([1,2,2,3,3])]2)filter+indexOf去重(兼容低版本浏览器)PlainText
arr.filter((item,index)=>arr.indexOf(item)===index)3)includes遍历去重,可识别undefined、NaN八、高频工程面试题21.防抖和节流的区别?手动实现答案:防抖:频繁触发事件,只在最后一次触发后延迟执行一次;适合输入框搜索、窗口resize。节流:频繁触发事件,固定时间间隔执行一次;适合滚动监听、按钮频繁点击、拖拽。防抖实现:PlainText
functiondebounce(fn,delay){
lettimer=null
returnfunction(...args){
clearTimeout(timer)
timer=setTimeout(()=>{
fn.apply(this,args)
},delay)
}
}节流实现:PlainText
functionthrottle(fn,interval
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025消防知识竞赛试题及答案
- 2025义务教育道德与法治课程标准必考题库含答案
- 2025主管护师考试全真模拟试题及答案
- 2026年《医疗器械冷链(运输、贮存)管理指南》培训试题及答案
- 2026年电子商务师一级考试题库及答案详解
- 中草药防治牛蛙肝脏肿大病
- 认识癌症专题知识讲座专家讲座
- 人工肱骨头置换的手术配合及护理
- 初中信息技术教资面试算法题库
- 健康宣教管理规范
- 绵阳中科绵投环境服务有限公司绵阳市餐厨废弃物资源化利用和无害化处理扩建项目(重新报批)环评报告
- 《幼儿营养与膳食管理》课件-【第4章】婴幼儿膳食的搭配制作
- 居间协议格式(2025年版)
- 门诊诊断培训班
- 《给排水管道工程技术》课件-管段水头损失计算
- 范里安微观经济学现代观点讲义
- 地质灾害调查与防治基础知识单选题100道及答案
- 2024-2025 学年人教版八年级地理上学期期中模拟卷【范围:第一章+第二章】
- 地图的阅读课件 2024-2025学年七年级地理上册同步课件(人教版2024)
- 《混凝土外加剂应用技术规程》
- 电动轮椅部件清单
评论
0/150
提交评论