版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
2025年js經(jīng)典面試題及答案1.如何準(zhǔn)確判斷變量類型?typeof和instanceof的局限性及替代方案typeof對基本類型(除null)能正確返回"number"、"string"、"boolean"、"undefined"、"symbol"、"bigint",但null返回"object",引用類型(數(shù)組、對象、正則等)均返回"object"。instanceof通過原型鏈判斷是否為構(gòu)造函數(shù)實(shí)例,但受原型鏈修改影響(如手動修改原型),且無法判斷原始類型(如newString('a')是String實(shí)例,但'a'不是)。更可靠的方案是Ototype.toString.call(),對任何值調(diào)用會返回[objectType]格式字符串,如:Ototype.toString.call(null)→"[objectNull]"Ototype.toString.call([])→"[objectArray]"Ototype.toString.call(newDate())→"[objectDate]"2.let、const、var的核心區(qū)別及塊級作用域的實(shí)際應(yīng)用var存在變量提升和函數(shù)作用域,let/const是塊級作用域({}內(nèi)有效)。let允許重新賦值,const聲明時必須初始化且不可重新綁定(但對象屬性可修改)。塊級作用域解決了循環(huán)綁定問題,例如:for(vari=0;i<3;i++){setTimeout(()=>console.log(i),0)//輸出3次3}for(leti=0;i<3;i++){setTimeout(()=>console.log(i),0)//輸出0、1、2(每次循環(huán)創(chuàng)建獨(dú)立i)}const在聲明配置對象時更安全,避免誤操作導(dǎo)致引用改變:constconfig={api:'/user'};config.api='/order';//允許(修改屬性)config={};//報錯(重新綁定)3.異步編程中微任務(wù)與宏任務(wù)的執(zhí)行順序,舉例說明事件循環(huán)過程微任務(wù)(Microtask)包括Promise.then/catch/finally、queueMicrotask()、MutationObserver回調(diào);宏任務(wù)(Macrotask)包括setTimeout、setInterval、setImmediate(Node)、I/O、UI渲染。事件循環(huán)執(zhí)行順序:執(zhí)行棧清空→處理微任務(wù)隊(duì)列(全部完成)→執(zhí)行宏任務(wù)隊(duì)列中的一個任務(wù)→重復(fù)。示例:console.log('start');setTimeout(()=>{console.log('setTimeout');Promise.resolve().then(()=>console.log('timeout-promise'));},0);Promise.resolve().then(()=>{console.log('promise1');queueMicrotask(()=>console.log('queueMicrotask'));}).then(()=>console.log('promise2'));console.log('end');執(zhí)行順序:start→end→promise1→promise2→queueMicrotask→setTimeout→timeout-promise解析:同步代碼執(zhí)行(start、end)→處理微任務(wù)隊(duì)列(Promise.then依次執(zhí)行,queueMicrotask加入當(dāng)前微任務(wù)隊(duì)列末尾)→執(zhí)行宏任務(wù)setTimeout(其內(nèi)部的Promise.then成為新的微任務(wù),在下一輪事件循環(huán)處理)4.閉包的定義、內(nèi)存管理問題及實(shí)際應(yīng)用場景閉包是函數(shù)與其詞法環(huán)境的組合,函數(shù)能訪問外層函數(shù)作用域的變量,即使外層函數(shù)已執(zhí)行完畢。內(nèi)存問題:閉包會導(dǎo)致外層函數(shù)的變量無法被GC回收,過度使用可能引發(fā)內(nèi)存泄漏。需注意在不需要時斷開引用(如將閉包變量置為null)。應(yīng)用場景:模塊封裝(暴露公共方法,隱藏私有變量):functioncreateCounter(){letcount=0;return{increment:()=>count++,get:()=>count};}constcounter=createCounter();//counter.increment()可訪問count,外部無法直接修改函數(shù)柯里化(保留參數(shù)):functionadd(a){return(b)=>a+b;}constadd5=add(5);//add5(3)→8事件處理器保留狀態(tài)(避免全局變量):functionbindButton(id){letclickCount=0;document.getElementById(id).addEventListener('click',()=>{clickCount++;console.log(`Clicked${clickCount}times`);});}5.原型鏈的查找機(jī)制,如何實(shí)現(xiàn)對象的繼承(至少3種方式)原型鏈?zhǔn)菍ο笸ㄟ^__proto__連接的原型對象鏈,用于實(shí)現(xiàn)繼承和屬性共享。查找屬性時,先查自身,再沿__proto__向上找,直到Ototype.__proto__(null)。繼承實(shí)現(xiàn)方式:組合繼承(ES5常用):functionParent(name){=name;}Ptotype.sayName=function(){console.log();};functionChild(name,age){Parent.call(this,name);//構(gòu)造函數(shù)繼承(避免原型屬性共享)this.age=age;}Ctotype=newParent();//原型鏈繼承(共享方法)Ctotype.constructor=Child;//修正constructor指向寄生組合式繼承(優(yōu)化組合繼承的多次調(diào)用父構(gòu)造函數(shù)問題):functioninherit(Child,Parent){Ctotype=Object.create(Ptotype);//創(chuàng)建空原型對象,原型指向PtotypeCtotype.constructor=Child;}inherit(Child,Parent);Ctotype.sayAge=function(){console.log(this.age);};ES6class繼承:classParent{constructor(name){=name;}sayName(){console.log();}}classChildextendsParent{constructor(name,age){super(name);//必須先調(diào)用super,否則無法訪問thisthis.age=age;}sayAge(){console.log(this.age);}}6.實(shí)現(xiàn)一個Promise.all,要求處理并發(fā)請求,當(dāng)任意一個reject時立即返回錯誤,否則返回所有結(jié)果數(shù)組functionpromiseAll(promises){returnnewPromise((resolve,reject)=>{if(!Array.isArray(promises)){returnreject(newTypeError('參數(shù)必須是數(shù)組'));}constresults=[];letcount=0;//已完成的數(shù)量constlen=promises.length;if(len===0)returnresolve(results);promises.forEach((promise,index)=>{Promise.resolve(promise)//處理非Promise值(轉(zhuǎn)為Promise.resolve).then((value)=>{results[index]=value;//按順序存儲結(jié)果if(++count===len){resolve(results);}}).catch((err)=>{reject(err);//任意一個reject,立即終止});});});}測試用例:promiseAll([Promise.resolve(1),2,//自動轉(zhuǎn)換為Promise.resolve(2)newPromise(resolve=>setTimeout(()=>resolve(3),100))]).then(res=>console.log(res));//[1,2,3](約100ms后輸出)promiseAll([Promise.resolve(1),Promise.reject('error')]).catch(err=>console.log(err));//'error'(立即輸出)7.如何理解JavaScript的執(zhí)行上下文?變量環(huán)境與詞法環(huán)境的區(qū)別執(zhí)行上下文(ExecutionContext)是JS代碼執(zhí)行時的環(huán)境,包含變量環(huán)境、詞法環(huán)境、this綁定。每次函數(shù)調(diào)用或全局代碼執(zhí)行時創(chuàng)建。變量環(huán)境(VariableEnvironment):存儲var聲明的變量和函數(shù)聲明(函數(shù)提升優(yōu)先級高于變量提升)。詞法環(huán)境(LexicalEnvironment):存儲let/const聲明的變量,以塊為作用域,使用鏈表結(jié)構(gòu)管理嵌套作用域。示例:functionfoo(){vara=1;letb=2;{letb=3;console.log(b);//3(詞法環(huán)境的塊作用域)}console.log(b);//2(外層詞法環(huán)境)console.log(a);//1(變量環(huán)境)}foo();執(zhí)行上下文創(chuàng)建階段:變量環(huán)境:a初始化為undefined(變量提升),foo函數(shù)聲明(如果是函數(shù)表達(dá)式則不同)。詞法環(huán)境:b在函數(shù)作用域初始化為未初始化(TDZ),塊作用域內(nèi)的b在塊執(zhí)行時初始化。8.什么是內(nèi)存泄漏?常見的導(dǎo)致內(nèi)存泄漏的場景及解決方法內(nèi)存泄漏指不再使用的內(nèi)存未被GC回收,導(dǎo)致可用內(nèi)存減少、程序性能下降。常見場景及解決:未移除的事件監(jiān)聽器:錯誤示例:element.addEventListener('click',handler);//元素被移除后,handler仍引用element,導(dǎo)致兩者都無法回收解決:element.removeEventListener('click',handler);或使用once選項(xiàng)({once:true})閉包中引用已銷毀的DOM:functionbindElement(){constel=document.getElementById('old-element');return()=>console.log(el.innerHTML);//閉包保留el引用,即使元素被移除}解決:在閉包外將el置為null,或使用WeakRef(實(shí)驗(yàn)性)全局變量:window.globalVar=data;//全局對象生命周期與頁面一致,未手動清理會一直存在解決:使用塊作用域(let/const)或模塊封裝定時器未清除:consttimer=setInterval(()=>{//操作已移除的DOM},1000);解決:clearInterval(timer)緩存未限制大小:constcache={};functionaddCache(key,value){cache[key]=value;//無限增長}解決:使用LRU緩存(限制最大數(shù)量,移除最久未使用的項(xiàng))9.如何實(shí)現(xiàn)一個線程安全的單例模式(保證多次實(shí)例化返回同一對象)單例模式確保類僅有一個實(shí)例,并提供全局訪問點(diǎn)。需考慮并發(fā)調(diào)用(如多個地方同時調(diào)用構(gòu)造函數(shù))和繼承場景。ES6class實(shí)現(xiàn)(使用Symbol防止屬性覆蓋):classSingleton{staticinstance;//私有靜態(tài)屬性(ES2022支持)constructor(){if(Singleton.instance){returnSingleton.instance;}//初始化邏輯this.data='initialdata';Singleton.instance=this;}}//兼容舊環(huán)境(ES5)的立即執(zhí)行函數(shù)模式:constSingleton=(function(){letinstance;returnfunction(){if(instance)returninstance;//初始化邏輯this.data='initialdata';instance=this;returninstance;};})();//線程安全(處理異步創(chuàng)建):classAsyncSingleton{staticinstancePromise;staticasyncgetInstance(){if(!this.instancePromise){this.instancePromise=newPromise((resolve)=>{//模擬異步初始化(如數(shù)據(jù)庫連接)setTimeout(()=>{constinstance=newAsyncSingleton();resolve(instance);},100);});}returnthis.instancePromise;}constructor(){/私有構(gòu)造函數(shù),防止直接new/}}//使用:AsyncSingleton.getInstance().then(instance=>{/使用實(shí)例/});10.解釋虛擬DOM的原理,與直接操作DOM相比的優(yōu)勢及局限性虛擬DOM(VirtualDOM)是真實(shí)DOM的JS對象表示(VDOM),通過diff算法比較新舊VDOM的差異,最終將最小化的操作應(yīng)用到真實(shí)DOM。原理步驟:首次渲染:將組件轉(zhuǎn)換為VDOM樹,渲染為真實(shí)DOM。狀態(tài)更新:提供新的VDOM樹,與舊樹進(jìn)行diff(深度優(yōu)先遍歷,同級比較)。patch操作:根據(jù)diff結(jié)果,只更新變化的節(jié)點(diǎn)(移動、新增、刪除)。優(yōu)勢:性能優(yōu)化:減少真實(shí)DOM操作次數(shù)(瀏覽器重排/重繪成本高)??缙脚_:VDOM可渲染為WebDOM、iOS/Android原生組件(如ReactNative)。組件化:通過VDOM的不可變性(immutable),方便管理組件狀態(tài)變化。局限性:首次渲染性能:VDOM需要額外JS計(jì)算,簡單頁面可能比直接操作DOM慢。內(nèi)存占用:維護(hù)VDOM樹需要額外內(nèi)存,復(fù)雜應(yīng)用可能增加內(nèi)存消耗。依賴diff算法優(yōu)化:低效的diff實(shí)現(xiàn)(如跨層級節(jié)點(diǎn)移動)可能導(dǎo)致性能下降。11.如何設(shè)計(jì)一個可復(fù)用的防抖(debounce)函數(shù),處理用戶輸入場景(要求支持立即執(zhí)行、取消功能)防抖函數(shù)確保在連續(xù)事件觸發(fā)時,僅最后一次觸發(fā)的回調(diào)在延遲后執(zhí)行。實(shí)現(xiàn):functiondebounce(func,wait=300,options={leading:false}){lettimer=null;letlastArgs=null;const{leading}=options;functiondebounced(...args){lastArgs=args;if(timer)clearTimeout(timer);//重置定時器if(leading&&!timer){//立即執(zhí)行(首次觸發(fā))func.apply(this,lastArgs);lastArgs=null;//避免重復(fù)執(zhí)行}timer=setTimeout(()=>{if(!leading){//非立即執(zhí)行模式func.apply(this,lastArgs);}timer=null;lastArgs=null;},wait);}debounced.cancel=()=>{clearTimeout(timer);timer=null;lastArgs=null;};returndebounced;}使用場景(搜索輸入):constsearchInput=document.getElementById('search');consthandleSearch=debounce((value)=>{console.log('搜索:',value);},500,{leading:false});searchInput.addEventListener('input',(e)=>{handleSearch(e.target.value);});//取消未執(zhí)行的請求(如組件卸載時)componentWillUnmount(){handleSearch.cancel();}12.解釋ES6Proxy的應(yīng)用場景,如何實(shí)現(xiàn)一個簡單的響應(yīng)式系統(tǒng)(類似Vue3的reactive)Proxy用于創(chuàng)建對象的代理,攔截并自定義基本操作(如屬性訪問、賦值、函數(shù)調(diào)用等)。應(yīng)用場景:數(shù)據(jù)校驗(yàn)、日志記錄、響應(yīng)式系統(tǒng)、函數(shù)參數(shù)攔截。實(shí)現(xiàn)簡單響應(yīng)式系統(tǒng):functionreactive(target){consthandlers={get(target,key,receiver){track(target,key);//收集依賴(將當(dāng)前副作用函數(shù)與屬性關(guān)聯(lián))returnReflect.get(target,key,receiver);},set(target,key,value,receiver){constoldValue=Reflect.get(target,key,receiver);constresult=Reflect.set(target,key,value,receiver);if(oldValue!==value){trigger(target,key);//觸發(fā)依賴(執(zhí)行關(guān)聯(lián)的副作用函數(shù))}returnresult;}};returnnewProxy(target,handlers);}//依賴收集與觸發(fā)(簡化版)consttargetMap=newWeakMap();//存儲target→key→副作用函數(shù)letactiveEffect=null;functiontrack(target,key){if(!activeEffect)return;letdepsMap=targetMap.get(target);if(!depsMap){depsMap=newMap();targetMap.set(target,depsMap);}letdep=depsMap.get(key);if(!dep){dep=newSet();depsMap.set(key,dep);}dep.add(activeEffect);//將副作用函數(shù)加入依賴集合}functiontrigger(target,key){constdepsMap=targetMap.get(target);if(!depsMap)return;constdep=depsMap.get(key);if(dep){dep.forEach(effect=>effect());//執(zhí)行所有關(guān)聯(lián)的副作用}}//使用示例conststate=reactive({count:0});effect(()=>{//定義副作用函數(shù)console.log(`當(dāng)前count:${state.count}`);});state.count=1;//觸發(fā)副作用,輸出"當(dāng)前count:1"state.count=1;//無變化,不觸發(fā)13.如何理解JavaScript的垃圾回收機(jī)制?常見的GC算法及現(xiàn)代瀏覽器的優(yōu)化策略JS引擎自動管理內(nèi)存,通過GC回收不再使用的內(nèi)存。常見GC算法:標(biāo)記-清除(Mark-Sweep):標(biāo)記活動對象(從根對象可達(dá)),清除未標(biāo)記對象。缺點(diǎn)是可能產(chǎn)生內(nèi)存碎片。標(biāo)記-整理(Mark-Compact):標(biāo)記后將活動對象向一端移動,整理內(nèi)存。解決碎片問題,但移動成本高。引用計(jì)數(shù)(ReferenceCounting):對象被引用次數(shù)為0時回收。無法處理循環(huán)引用(如a.b=b;b.a=a)。現(xiàn)代瀏覽器(如V8)的優(yōu)化策略:分代回收(GenerationalCollection):將內(nèi)存分為新生代(新對象)和老生代(存活久的對象)。新生代:使用復(fù)制算法(將內(nèi)存分為From和To空間,存活對象復(fù)制到To,交換空間),回收頻率高,速度快。老生代:使用標(biāo)記-清除+標(biāo)記-整理,減少復(fù)制開銷。增量回收(IncrementalGC):將GC分成小任務(wù),穿插在JS執(zhí)行中,減少卡頓(如Chrome的Orinoco項(xiàng)目)。并行回收(ParallelGC):利用多核CPU,同時執(zhí)行多個GC線程,加快回收速度。14.實(shí)現(xiàn)一個函數(shù),將任意嵌套的數(shù)組展平為一維數(shù)組(如[1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年白銀市特崗教師招聘考試真題題庫附答案
- 2024年黑河學(xué)院輔導(dǎo)員招聘備考題庫附答案
- 2025天津市公務(wù)員考試數(shù)量關(guān)系專項(xiàng)練習(xí)題及答案參考
- 水盆工保密意識測試考核試卷含答案
- 電法勘探工崗前成果考核試卷含答案
- 幻燈機(jī)與投影機(jī)維修工安全實(shí)操考核試卷含答案
- 排水管道工安全行為能力考核試卷含答案
- 固體化妝品制造工安全知識能力考核試卷含答案
- 硝酸銨結(jié)晶造粒工保密競賽考核試卷含答案
- 2024年湖北大學(xué)知行學(xué)院輔導(dǎo)員招聘考試真題匯編附答案
- 04S519小型排水構(gòu)筑物1
- 光纖激光打標(biāo)機(jī)說明書
- 勞動者個人職業(yè)健康監(jiān)護(hù)檔案
- 《兩角和與差的正弦、余弦、正切公式》示范公開課教學(xué)PPT課件【高中數(shù)學(xué)人教版】
- 治理現(xiàn)代化下的高校合同管理
- 境外宗教滲透與云南邊疆民族地區(qū)意識形態(tài)安全研究
- GB/T 28920-2012教學(xué)實(shí)驗(yàn)用危險固體、液體的使用與保管
- GB/T 26389-2011衡器產(chǎn)品型號編制方法
- GB/T 16588-2009帶傳動工業(yè)用多楔帶與帶輪PH、PJ、PK、PL和PM型:尺寸
- 人大企業(yè)經(jīng)濟(jì)學(xué)考研真題-802經(jīng)濟(jì)學(xué)綜合歷年真題重點(diǎn)
- 建筑抗震鑒定標(biāo)準(zhǔn)課件
評論
0/150
提交評論