JS 视频面试高频题及详细答案(实战口语版)_第1页
JS 视频面试高频题及详细答案(实战口语版)_第2页
JS 视频面试高频题及详细答案(实战口语版)_第3页
JS 视频面试高频题及详细答案(实战口语版)_第4页
JS 视频面试高频题及详细答案(实战口语版)_第5页
已阅读5页,还剩4页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JS视频面试高频题及详细答案(实战口语版)一、JS基础核心题1、说说var、let、const的区别?参考答案:首先是变量提升不一样,var存在变量提升,声明前调用会返回undefined;let和const没有变量提升,声明前使用会直接报错,也就是暂时性死区。其次是作用域不同,var只有全局作用域和函数作用域,没有块级作用域,for循环嵌套很容易出现变量泄露的问题;let和const支持块级作用域,大括号内部声明的变量,外部访问不到,解决了循环变量污染的问题。最后是赋值规则,var和let可以重复赋值、可修改;const声明的是常量,一旦赋值不能修改,而且必须初始化。另外要注意,const声明引用类型(对象、数组)时,内部属性可以修改,只是不能重新赋值。2、JS基本数据类型有哪些?和引用类型的区别?参考答案:基本数据类型有7种:string、number、boolean、undefined、null、symbol、bigInt。引用类型主要是:Object、Array、Function、Date、RegExp等。核心区别有两点:第一是存储方式,基本类型的值直接存在栈内存中,赋值是完整拷贝一份值,两个变量互不影响;引用类型栈内存存的是地址,真实数据存在堆内存里,赋值只是拷贝地址,两个变量指向同一个数据,修改一个另一个也会变。第二是比较规则,基本类型比较的是值本身;引用类型比较的是内存地址,哪怕两个对象内容一模一样,地址不同也不相等。3、null和undefined的区别?参考答案:undefined代表未定义,变量声明了但没赋值、函数没有返回值、对象不存在的属性,获取到的都是undefined。null代表空对象,是主动手动赋值的空值,一般用来清空对象、主动释放引用。另外类型不一样,typeofundefined是undefined;typeofnull会返回object,这是JS初期的一个历史bug。还有相等判断,null==undefined为true,null===undefined为false。4、==和===的区别?参考答案:==是宽松相等,会先进行隐式类型转换,类型不一样会自动转成相同类型再比较值;===是严格相等,必须类型和值完全一致才为true,不会做任何类型转换。日常开发中优先用===,可以避免很多隐式转换带来的诡异问题,比如0==false、''==false这种成立的情况,严格相等下都是false。唯一常用==的场景:判断变量是否为null或undefined,if(val==null)可以一次性匹配两种空值。二、作用域与闭包高频题1、什么是作用域?JS有哪些作用域?参考答案:作用域就是变量、函数的可访问范围,用来控制变量的生效和失效,避免全局变量随意污染。JS主要有三种作用域:1.全局作用域:页面全局生效,任何地方都能访问;2.函数作用域:仅在函数内部生效,函数执行结束变量销毁;3.块级作用域:由let、const产生,大括号(if、for、while)内部独立生效。2、什么是闭包?闭包的用途和弊端?参考答案:闭包简单说就是内层函数访问外层函数的变量,并且外层函数执行结束后,内层函数依然可以持有外层的变量,不会被垃圾回收。核心条件:函数嵌套+内部函数引用外部变量+内部函数被外部调用。闭包的用途:1.实现私有变量,避免全局变量污染;2.保存函数执行的上下文状态,比如循环定时器、事件回调;3.实现柯里化、模块化思想。闭包的弊端:因为变量会一直被保留,不会销毁,容易造成内存泄漏,大量使用会导致页面卡顿。解决办法就是用完手动置空变量,主动释放内存。3、讲讲变量提升和函数提升参考答案:JS代码执行前会先做预解析,把变量和函数的声明提升到当前作用域的最顶部。变量提升只提升声明,不提升赋值,所以var变量声明前调用是undefined;let、const有暂时性死区,不会提升,提前调用报错。函数提升优先级比变量提升高,整个函数体都会被提升,所以函数可以在声明前直接调用。注意:函数表达式不会提升,只有普通声明式函数才会提升。三、原型与原型链面试题1、什么是原型?什么是原型链?参考答案:JS中每个函数都有prototype属性,也就是显式原型,用来存放公共的方法和属性,供所有实例共享,节省内存。每个实例对象都有__proto__属性,也就是隐式原型,指向构造函数的prototype。原型链就是对象的__proto__层层向上查找的链条。当访问一个对象的属性或方法时,先在自身找,找不到就去__proto__指向的原型上找,一直找到Ototype,最后到null,这个查找链路就是原型链。2、constructor、prototype、__proto__的关系?参考答案:1.构造函数的prototype是原型对象;2.原型对象的constructor指回构造函数本身;3.实例对象的__proto__指向构造函数的prototype;简单总结:实例.__proto__===构造函数.prototype,原型.constructor===构造函数。3、如何判断一个变量是不是数组?参考答案:有三种常用方法,面试优先说最靠谱的:1.Ototype.toString.call(arr)==='[objectArray]',最准确,能区分所有引用类型,不会出错;2.Array.isArray(arr),ES5新增,专门判断数组,简洁好用,项目中最常用;3.arrinstanceofArray,弊端是跨页面、跨框架会失效,因为不同窗口的Array构造函数不一样。四、异步JS与事件循环1、JS为什么是单线程?什么是同步异步?参考答案:JS最初是为浏览器交互设计的,主要操作DOM,如果是多线程,多个线程同时修改DOM会出现冲突,所以设计成单线程。同步代码:从上到下依次执行,上一行执行完才会执行下一行,阻塞后续代码;异步代码:不会阻塞主线程,耗时操作(定时器、接口请求、事件监听)放入异步队列,主线程同步代码执行完再执行异步代码。2、讲讲JS事件循环机制(EventLoop)参考答案:整体流程很简单:先执行同步代码,同步执行完后,再执行微任务,微任务清空后,执行宏任务,每执行完一个宏任务,就再次清空微任务,循环往复,这就是事件循环。常见微任务:Promise.then/catch/finally、async/await、queueMicrotask;常见宏任务:setTimeout、setInterval、AJAX请求、DOM事件。优先级:同步代码>微任务>宏任务。3、Promise的理解?三种状态?参考答案:Promise是解决异步回调地狱的方案,用来优雅处理异步操作,避免多层嵌套回调,让异步代码扁平化。Promise有三种状态,且状态一旦改变就不可逆:1.pending:初始等待状态,异步操作未完成;2.fulfilled:成功状态,执行resolve();3.rejected:失败状态,执行reject()。常用方法:then接收成功结果,catch捕获错误,finally无论成功失败都会执行,还有all、race、allSettled等批量处理方法。4、async/await的作用和原理?参考答案:async/await是Promise的语法糖,让异步代码可以像同步代码一样书写,可读性极强,是现在项目主流的异步写法。async修饰函数,函数返回值会自动包装成Promise;await只能在async函数内部使用,作用是阻塞代码,等待Promise执行完成,拿到结果后再执行后续代码。错误处理一般用try/catch包裹await代码,捕获异步错误。五、数组与对象常用方法1、数组map、forEach、filter、reduce的区别?参考答案:1.forEach:单纯遍历数组,没有返回值,适合只执行操作、不需要返回新数组的场景;2.map:遍历并返回新数组,可以对每一项做加工处理,长度和原数组一致,适合数据映射;3.filter:过滤数组,返回符合条件的新数组,不满足条件的直接剔除,数组长度会改变;4.reduce:累加器,功能最强,可以实现求和、去重、扁平化、对象统计等,能拿到累计结果。2、数组去重有哪些方法?参考答案:1.ES6Set去重,最简单:[...newSet(arr)],适合纯数字、字符串数组,简洁高效;2.filter+indexOf,通过判断元素索引去重,兼容低版本浏览器;3.reduce遍历去重,灵活性高,还能实现对象数组根据某个字段去重。六、this指向经典面试题1、说说this的指向规则?参考答案:this的指向只看调用方式,不看定义位置,有五种核心情况:1.普通函数直接调用:this指向window(浏览器)/global(node);2.对象方法调用:this指向调用的对象;3.构造函数调用:this指向new出来的实例对象;4.箭头函数:没有自己的this,继承外层作用域的this,且永远不会改变;5.call、apply、bind:强制修改this指向,指向传入的第一个参数。2、call、apply、bind的区别?参考答案:三者都是用来修改函数this指向的,核心区别在执行方式和传参:1.call:立即执行函数,参数是逐个传入(this,参数1,参数2);2.apply:立即执行函数,参数是数组形式传入(this,[参数数组]);3.bind:不会立即执行,返回一个修改完this的新函数,需要手动调用,传参方式和call一致。七、垃圾回收与内存优化1、JS垃圾回收机制了解吗?参考答案:JS是自动垃圾回收语言,不需要手动申请和释放内存,引擎会自动回收不使用的变量,释放内存。主要两种回收方式:1.标记清除:最主流,遍历所有变量,标记正在使用的,清除未标记的闲置变量;2.引用计数:判断变量引用次数,次数为0就回收,缺点是无法解决循环引用问题。2、前端常见的内存泄漏场景?参考答案:1.全局变量过多,未手动销毁;2.闭包滥用,导致变量无法回收;3.定时器、事件监听未及时清除;4.缓存过多无用数据、DOM节点引用未清空。解决方式:及时清空定时器、解绑事件、关闭页面置空全局变量、减少无效闭包。八、手写代码高频面试题(带答案)1、手写防抖函数参考答案:javascript

//防抖:触发事件后,延迟n秒执行,期间再次触发重新计时

functiondebounce(fn,delay){

lettimer=null

returnfunction(...args){

if(timer)clearTimeout(timer)

timer=setTimeout(()=>{

fn.apply(this,args)

timer=null

},delay)

}

}2、手写节流函数参考答案:javascript

//节流:固定时间内只执行一次,防止高频触发

functionthrottle(fn,interval){

letflag=true

returnfunction(...args){

if(!flag)return

flag=false

setTimeout(()=>{

fn.apply(this,args)

flag=true

},interval)

}

}3、手写简易Promise参考答案:javascript

classMyPromise{

constructor(executor){

this.status='pending'

this.value=null

this.reason=null

this.onFulfilledCb=[]

this.onRejectedCb=[]

constresolve=(value)=>{

if(this.status==='pending'){

this.status='fulfilled'

this.value=value

this.onFulfilledCb.forEach(cb=>cb())

}

}

constreject=(reason)=>{

if(this.status==='pending'){

this.status='rejected'

this.reason=reason

this.onRejectedCb.forEach(cb=>cb())

}

}

executor(resolve,reject)

}

then(onFulfilled,onRejected){

if(this.statu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论