JS核心知識(shí)點(diǎn)之箭頭函數(shù)與this詳細(xì)解析
一.數(shù)組去重的方式有那些?
數(shù)組去重的核心是篩選出數(shù)組中唯一不重復(fù)的元素,推薦優(yōu)先使用ES6,代碼簡(jiǎn)潔,性能優(yōu)異
1.Set配合擴(kuò)展運(yùn)算符
Set 是 ES6 提供的不允許重復(fù)值的集合,配合擴(kuò)展運(yùn)算符 /Array.from 可快速去重。

2.利用indexOf/includes 遍歷判斷
遍歷數(shù)組,用 indexOf(返回 - 1 表示不存在)或 includes(返回布爾值)判斷元素是否已存在于新數(shù)組,不存在加入新數(shù)組,存在則不加入

還可以使用forEach+includes實(shí)現(xiàn)

3.利用filter + indexOf/Set(篩選式去重)

二.講述一下手寫(xiě)深拷貝的邏輯
核心就 3 步,抓住本質(zhì)即可:
- 判斷類型:如果是基本類型 /
null,直接返回(無(wú)需拷貝); - 創(chuàng)建容器:區(qū)分?jǐn)?shù)組和普通對(duì)象,創(chuàng)建對(duì)應(yīng)的空新對(duì)象 / 新數(shù)組;
- 遞歸拷貝:遍歷原數(shù)據(jù)的屬性 / 元素,遞歸調(diào)用深拷貝,賦值給新容器。
滿足絕大多數(shù)簡(jiǎn)單場(chǎng)景簡(jiǎn)化版手寫(xiě)代碼

以下是測(cè)試

總結(jié):
- 簡(jiǎn)化版深拷貝的核心是「類型判斷 + 遞歸拷貝」,3 步即可實(shí)現(xiàn)普通場(chǎng)景的深拷貝需求。
- 基礎(chǔ)簡(jiǎn)化版足以應(yīng)對(duì)日常大部分簡(jiǎn)單場(chǎng)景(基本類型、普通對(duì)象、數(shù)組)。
三.this指向的理解
1.this的核心本質(zhì):this 是 JavaScript 中的關(guān)鍵字,它的指向不是在定義時(shí)確定的,而是在函數(shù)調(diào)用時(shí)確定的(即 “調(diào)用時(shí)綁定”)。簡(jiǎn)單說(shuō):this 指向的是「調(diào)用函數(shù)的那個(gè)對(duì)象」,誰(shuí)調(diào)用函數(shù),this 就指向誰(shuí)。
2.this 的 4 種核心綁定規(guī)則(從常用到特殊):
1.默認(rèn)綁定(獨(dú)立函數(shù)調(diào)用)
當(dāng)函數(shù)獨(dú)立調(diào)用(沒(méi)有明確的調(diào)用對(duì)象)時(shí),this 指向全局對(duì)象
瀏覽器環(huán)境:全局對(duì)象是 window。
Node.js 環(huán)境:全局對(duì)象是 global。
嚴(yán)格模式(use strict):默認(rèn)綁定的 this 是 undefined

2.隱式綁定
當(dāng)函數(shù)作為對(duì)象的方法被調(diào)用時(shí),this 指向這個(gè)調(diào)用函數(shù)的對(duì)象(即 “點(diǎn)前面的對(duì)象”)

3. 顯式綁定(手動(dòng)指定 this)
通過(guò) call、apply、bind 方法,可以手動(dòng)指定 this 的指向,不受調(diào)用方式影響。
call/apply:立即執(zhí)行函數(shù),第一個(gè)參數(shù)是 this 指向的對(duì)象
bind:返回一個(gè)新函數(shù)(不立即執(zhí)行),新函數(shù)的 this 永久綁定為第一個(gè)參數(shù)

4.new綁定
當(dāng)函數(shù)作為構(gòu)造函數(shù)(用 new 關(guān)鍵字調(diào)用)時(shí),this 指向新建的實(shí)例對(duì)象。

5.特殊場(chǎng)景 箭頭函數(shù)
箭頭函數(shù)沒(méi)有自己的 this,它的 this 是繼承自外層作用域的 this(定義時(shí)確定,而非調(diào)用時(shí)),不受綁定規(guī)則影響。

總結(jié):
this指向是「調(diào)用時(shí)確定」的,核心原則是 “誰(shuí)調(diào)用,指向誰(shuí)”(箭頭函數(shù)除外)。- 核心綁定規(guī)則:默認(rèn)綁定(全局 /undefined)、隱式綁定(對(duì)象方法)、顯式綁定(call/apply/bind)、new 綁定(構(gòu)造函數(shù)實(shí)例)。
- 箭頭函數(shù)無(wú)自身
this,繼承外層作用域的this(定義時(shí)確定)。 - 綁定優(yōu)先級(jí):
new 綁定 > 顯式綁定 > 隱式綁定 > 默認(rèn)綁定。
四. 如何使用promise封裝原生ajax?
封裝思路
- 創(chuàng)建 Promise 實(shí)例:用 Promise 包裹 AJAX 邏輯,成功時(shí)調(diào)用
resolve,失敗時(shí)調(diào)用reject。 - 創(chuàng)建 XHR 對(duì)象:通過(guò)
new XMLHttpRequest()生成 AJAX 核心對(duì)象。 - 配置請(qǐng)求:調(diào)用
open()方法設(shè)置請(qǐng)求方式、URL、是否異步。 - 處理響應(yīng):監(jiān)聽(tīng)
onload事件(請(qǐng)求完成),判斷響應(yīng)狀態(tài)碼,成功則傳遞響應(yīng)數(shù)據(jù),失敗則傳遞錯(cuò)誤信息。 - 處理網(wǎng)絡(luò)錯(cuò)誤:監(jiān)聽(tīng)
onerror事件(網(wǎng)絡(luò)異常),觸發(fā)reject。 - 發(fā)送請(qǐng)求:調(diào)用
send()方法,攜帶請(qǐng)求體(POST 請(qǐng)求時(shí)使用)。 - 可選配置:設(shè)置請(qǐng)求頭(如 POST 請(qǐng)求的
Content-Type)。
注意事項(xiàng)
- 跨域問(wèn)題:原生 AJAX 受同源策略限制,跨域需后端配置 CORS 或使用 JSONP(本封裝不支持 JSONP)。
- 請(qǐng)求體格式:如果需要提交表單數(shù)據(jù)(
application/x-www-form-urlencoded),需將data轉(zhuǎn)為key=value格式,并對(duì)應(yīng)設(shè)置請(qǐng)求頭。 - 兼容性:
XMLHttpRequest支持 IE7 及以上瀏覽器,如需兼容更低版本,需使用ActiveXObject(極少場(chǎng)景需要)。
總結(jié)
- 核心是用 Promise 包裹原生 AJAX 流程,成功調(diào)用
resolve、失敗調(diào)用reject,實(shí)現(xiàn)異步流程的優(yōu)雅管理。 - 封裝關(guān)鍵步驟:創(chuàng)建 XHR 對(duì)象 → 配置請(qǐng)求 → 設(shè)置請(qǐng)求頭 → 處理響應(yīng) / 錯(cuò)誤 → 發(fā)送請(qǐng)求。
- 使用時(shí)通過(guò)
then接收成功數(shù)據(jù)、catch捕獲錯(cuò)誤,支持 GET/POST 等常見(jiàn)請(qǐng)求方式,可靈活配置參數(shù)。 - 該封裝支持 JSON 格式請(qǐng)求 / 響應(yīng),自動(dòng)拼接 GET 參數(shù),具備默認(rèn)配置,可直接用于日常簡(jiǎn)單接口請(qǐng)求。
五. 箭頭函數(shù)和普通函數(shù)的區(qū)別?
箭頭函數(shù)是ES6新增的函數(shù)語(yǔ)法,與普通函數(shù)(ES5函數(shù))相比,核心區(qū)別體現(xiàn)在6個(gè)方面,具體如下:
this指向不同(核心區(qū)別):普通函數(shù)的this指向動(dòng)態(tài)變化,取決于調(diào)用方式(全局調(diào)用指向window/global,對(duì)象方法調(diào)用指向該對(duì)象,構(gòu)造函數(shù)調(diào)用指向?qū)嵗琧all/apply/bind可手動(dòng)改變this);箭頭函數(shù)沒(méi)有自己的this,其this繼承自外層作用域的this,且一旦確定無(wú)法改變(call/apply/bind對(duì)其this無(wú)效,僅能傳遞參數(shù))。
構(gòu)造函數(shù)特性:普通函數(shù)可作為構(gòu)造函數(shù)使用new關(guān)鍵字創(chuàng)建實(shí)例(此時(shí)this指向?qū)嵗?;箭頭函數(shù)不能作為構(gòu)造函數(shù),使用new調(diào)用會(huì)拋出TypeError錯(cuò)誤(因箭頭函數(shù)沒(méi)有prototype屬性)。
arguments對(duì)象:普通函數(shù)內(nèi)部有arguments對(duì)象,用于存儲(chǔ)實(shí)參列表(類數(shù)組,可通過(guò)Array.from轉(zhuǎn)換為數(shù)組);箭頭函數(shù)沒(méi)有arguments對(duì)象,若需獲取實(shí)參,可使用剩余參數(shù)(...args)。
prototype屬性:普通函數(shù)有prototype屬性,其原型上的方法可被實(shí)例繼承;箭頭函數(shù)沒(méi)有prototype屬性。
函數(shù)體簡(jiǎn)化:箭頭函數(shù)支持簡(jiǎn)潔語(yǔ)法,若函數(shù)體只有一條return語(yǔ)句,可省略大括號(hào)和return關(guān)鍵字(如(a,b) => a+b);若返回對(duì)象,需用小括號(hào)包裹(如(a,b) => ({name: a, age: b}));普通函數(shù)無(wú)此簡(jiǎn)化語(yǔ)法。
不能用作Generator函數(shù):箭頭函數(shù)不能使用yield關(guān)鍵字,無(wú)法作為Generator函數(shù);普通函數(shù)可以。
六. 瀏覽器環(huán)境中事件循環(huán)的理解?
瀏覽器環(huán)境的事件循環(huán)(Event Loop)是JavaScript解決單線程執(zhí)行阻塞問(wèn)題的核心機(jī)制,其本質(zhì)是協(xié)調(diào)調(diào)用棧、宏任務(wù)隊(duì)列(Macro Task Queue)和微任務(wù)隊(duì)列(Micro Task Queue)的執(zhí)行順序,確保異步任務(wù)有序執(zhí)行,具體邏輯和流程如下:
核心前提:JavaScript是單線程語(yǔ)言,同一時(shí)間只能執(zhí)行一個(gè)任務(wù),若直接執(zhí)行異步任務(wù)(如定時(shí)器、網(wǎng)絡(luò)請(qǐng)求、DOM事件)會(huì)導(dǎo)致阻塞,因此需要事件循環(huán)機(jī)制區(qū)分同步/異步任務(wù)的執(zhí)行時(shí)機(jī)。
關(guān)鍵組件:
調(diào)用棧:用于執(zhí)行同步任務(wù)的棧結(jié)構(gòu),遵循“先進(jìn)后出”原則,函數(shù)調(diào)用時(shí)入棧,執(zhí)行完畢后出棧;
宏任務(wù)隊(duì)列:存儲(chǔ)宏任務(wù)(異步任務(wù)的一種),常見(jiàn)類型有:script(整體代碼)、setTimeout/setInterval、I/O操作(如文件讀?。?、UI渲染、requestAnimationFrame;
微任務(wù)隊(duì)列:存儲(chǔ)微任務(wù)(異步任務(wù)的一種),常見(jiàn)類型有:Promise.then/catch/finally、MutationObserver、process.nextTick(Node環(huán)境特有,瀏覽器無(wú))、queueMicrotask。
執(zhí)行流程(核心規(guī)則):
1. 先執(zhí)行調(diào)用棧中的同步任務(wù),直到調(diào)用棧為空;
2. 執(zhí)行微任務(wù)隊(duì)列中的所有微任務(wù)(按隊(duì)列順序依次執(zhí)行),直到微任務(wù)隊(duì)列為空;
3. 執(zhí)行一次宏任務(wù)隊(duì)列中的第一個(gè)宏任務(wù),將其推入調(diào)用棧執(zhí)行,執(zhí)行完畢后調(diào)用棧為空;
4. 重復(fù)步驟2-3,形成循環(huán)(即“事件循環(huán)”)。
注意點(diǎn):
整體script代碼屬于宏任務(wù),優(yōu)先執(zhí)行;
微任務(wù)的執(zhí)行優(yōu)先級(jí)高于宏任務(wù),每次執(zhí)行完一個(gè)宏任務(wù)后,必須清空所有微任務(wù)再執(zhí)行下一個(gè)宏任務(wù);
UI渲染任務(wù)在微任務(wù)隊(duì)列清空后、下一個(gè)宏任務(wù)執(zhí)行前進(jìn)行(不同瀏覽器可能有細(xì)微差異,但核心邏輯一致)。
七. === 和 Object.is() 的區(qū)別?
===(嚴(yán)格相等運(yùn)算符)和Object.is()都是JavaScript中用于判斷兩個(gè)值是否“嚴(yán)格相等”的方式,但二者在處理特殊值(如NaN、0和-0)時(shí)存在差異,核心區(qū)別如下:
核心一致點(diǎn):均不進(jìn)行類型轉(zhuǎn)換,直接比較值的類型和具體值,若類型不同則直接返回false(這一點(diǎn)區(qū)別于==,==會(huì)先進(jìn)行類型轉(zhuǎn)換再比較值)。
關(guān)鍵差異點(diǎn)(特殊值處理):
處理NaN:===認(rèn)為NaN !== NaN(這是JavaScript的設(shè)計(jì)缺陷,NaN與任何值都不相等,包括自身);而Object.is(NaN, NaN)返回true(修復(fù)了NaN的比較問(wèn)題)。
處理0和-0:===認(rèn)為+0 === -0(因?yàn)槎咴跀?shù)值上等價(jià));而Object.is(+0, -0)返回false(因?yàn)?0和-0在底層存儲(chǔ)和某些運(yùn)算場(chǎng)景中存在差異,如1/+0=+Infinity,1/-0=-Infinity)。
普通值比較一致性:對(duì)于除NaN、+0、-0之外的普通值,二者結(jié)果完全一致。例如:
5 === 5 → true;Object.is(5,5) → true;
'5' === 5 → false;Object.is('5',5) → false;
null === undefined → false;Object.is(null, undefined) → false。
總結(jié):Object.is()可以理解為“更嚴(yán)格的===”,它修正了===在NaN和+0/-0比較上的不合理之處,更符合直覺(jué)上的“值相等”判斷。
八. promise的理解?
Promise是ES6引入的異步編程解決方案,用于解決傳統(tǒng)回調(diào)函數(shù)(回調(diào)地獄)的問(wèn)題,其本質(zhì)是一個(gè)狀態(tài)容器,存儲(chǔ)著異步操作的結(jié)果(未完成/已完成/已失?。?,并提供統(tǒng)一的API供開(kāi)發(fā)者處理異步結(jié)果,核心特性和用法如下:
核心定義:Promise是一個(gè)構(gòu)造函數(shù),可通過(guò)new Promise((resolve, reject) => { ... })創(chuàng)建實(shí)例,接收一個(gè)“執(zhí)行器函數(shù)”作為參數(shù),執(zhí)行器函數(shù)立即執(zhí)行,內(nèi)部包含異步操作邏輯。
三個(gè)狀態(tài)(不可逆):注意:狀態(tài)一旦從pending轉(zhuǎn)為fulfilled或rejected,就無(wú)法再改變。
pending(等待態(tài)):初始狀態(tài),異步操作未完成;
fulfilled(成功態(tài)):異步操作完成,調(diào)用resolve()后從pending轉(zhuǎn)為fulfilled,狀態(tài)固定;
rejected(失敗態(tài)):異步操作失敗,調(diào)用reject()后從pending轉(zhuǎn)為rejected,狀態(tài)固定。
核心方法(原型方法):
then():接收兩個(gè)可選參數(shù)(成功回調(diào)、失敗回調(diào)),用于處理fulfilled和rejected狀態(tài)的結(jié)果;then()方法返回一個(gè)新的Promise實(shí)例,因此支持鏈?zhǔn)秸{(diào)用(解決回調(diào)地獄的核心);
catch():專門處理rejected狀態(tài)的結(jié)果,等價(jià)于then(null, 失敗回調(diào));通常用于鏈?zhǔn)秸{(diào)用的末尾,統(tǒng)一捕獲前面所有異步操作的錯(cuò)誤;
finally():無(wú)論P(yáng)romise狀態(tài)是fulfilled還是rejected,都會(huì)執(zhí)行的回調(diào);finally()返回一個(gè)新的Promise,且回調(diào)函數(shù)不接收任何參數(shù)(無(wú)法獲取異步結(jié)果),主要用于執(zhí)行清理操作(如關(guān)閉加載動(dòng)畫(huà))。
靜態(tài)方法(工具方法):
Promise.resolve(value):快速創(chuàng)建一個(gè)fulfilled狀態(tài)的Promise,value為成功結(jié)果;若value本身是Promise,則直接返回該P(yáng)romise;
Promise.reject(reason):快速創(chuàng)建一個(gè)rejected狀態(tài)的Promise,reason為失敗原因;
Promise.all(iterable):接收一個(gè)可迭代對(duì)象(如數(shù)組),包含多個(gè)Promise;只有所有Promise都變?yōu)閒ulfilled,才返回fulfilled狀態(tài)的Promise(結(jié)果為所有Promise成功結(jié)果的數(shù)組);只要有一個(gè)Promise變?yōu)閞ejected,立即返回rejected狀態(tài)的Promise(結(jié)果為第一個(gè)失敗的原因);
Promise.race(iterable):接收可迭代對(duì)象,返回一個(gè)新Promise;只要有一個(gè)Promise狀態(tài)改變(fulfilled或rejected),就立即返回該狀態(tài)的結(jié)果(“競(jìng)速”機(jī)制);
Promise.allSettled(iterable):接收可迭代對(duì)象,等待所有Promise都完成(無(wú)論成功或失?。┖螅祷豧ulfilled狀態(tài)的Promise,結(jié)果為每個(gè)Promise的狀態(tài)和結(jié)果組成的數(shù)組(解決了Promise.all()一個(gè)失敗就整體失敗的問(wèn)題);
Promise.any(iterable):接收可迭代對(duì)象,只要有一個(gè)Promise變?yōu)閒ulfilled,就返回fulfilled狀態(tài)的結(jié)果;只有所有Promise都變?yōu)閞ejected,才返回rejected狀態(tài)的Promise(與Promise.all()相反)。
核心優(yōu)勢(shì):解決回調(diào)地獄(回調(diào)嵌套過(guò)深導(dǎo)致的代碼可讀性差、維護(hù)困難),通過(guò)鏈?zhǔn)秸{(diào)用將異步操作線性化;統(tǒng)一異步操作的錯(cuò)誤處理機(jī)制(catch()統(tǒng)一捕獲)。
注意點(diǎn):Promise一旦創(chuàng)建,執(zhí)行器函數(shù)立即執(zhí)行,無(wú)法中途取消;若未添加catch()捕獲錯(cuò)誤,失敗狀態(tài)的Promise會(huì)拋出未捕獲錯(cuò)誤,影響程序執(zhí)行。
九. 遞歸函數(shù)的理解?
遞歸函數(shù)是指在函數(shù)內(nèi)部直接或間接調(diào)用自身的函數(shù),是一種常用的編程思想,核心用于將復(fù)雜的大問(wèn)題拆解為與原問(wèn)題結(jié)構(gòu)相似的小問(wèn)題,通過(guò)解決小問(wèn)題最終解決大問(wèn)題,其核心要素和注意事項(xiàng)如下:
核心組成(兩個(gè)必要條件):
遞歸終止條件(基線條件):函數(shù)必須有一個(gè)明確的終止條件,當(dāng)滿足該條件時(shí)停止調(diào)用自身,否則會(huì)導(dǎo)致無(wú)限遞歸(棧溢出錯(cuò)誤,如Maximum call stack size exceeded);
遞歸遞推條件(遞歸步驟):函數(shù)在內(nèi)部調(diào)用自身時(shí),必須將問(wèn)題規(guī)??s小(即傳遞的參數(shù)更接近終止條件),確保最終能觸發(fā)終止條件。
執(zhí)行原理:遞歸函數(shù)的執(zhí)行依賴調(diào)用棧,每次調(diào)用自身時(shí),會(huì)將當(dāng)前函數(shù)的執(zhí)行上下文(參數(shù)、局部變量、執(zhí)行位置)壓入調(diào)用棧;當(dāng)觸發(fā)終止條件后,函數(shù)開(kāi)始逐步返回,同時(shí)從調(diào)用棧中彈出執(zhí)行上下文,依次執(zhí)行剩余邏輯。
典型應(yīng)用場(chǎng)景:
數(shù)學(xué)問(wèn)題:計(jì)算階乘(n! = n × (n-1) × ... × 1)、斐波那契數(shù)列、冪運(yùn)算等;
數(shù)據(jù)結(jié)構(gòu)操作:遍歷樹(shù)(二叉樹(shù)前序/中序/后序遍歷)、圖的深度優(yōu)先搜索(DFS)、鏈表反轉(zhuǎn)等;
復(fù)雜邏輯拆解:如文件目錄遍歷(多層嵌套目錄的讀取)。
示例(計(jì)算n的階乘):
// 遞歸函數(shù):計(jì)算n的階乘 function factorial(n) { // 終止條件:n=1時(shí)返回1 (1! = 1) if (n === 1) return 1; // 遞推條件:n! = n × (n-1)!,縮小問(wèn)題規(guī)模 (n-1) return n * factorial(n - 1); } factorial(5); // 結(jié)果:120(5×4×3×2×1) }優(yōu)缺點(diǎn):
優(yōu)點(diǎn):代碼簡(jiǎn)潔、邏輯清晰,能直觀體現(xiàn)問(wèn)題的遞歸結(jié)構(gòu);
缺點(diǎn):遞歸調(diào)用會(huì)占用額外的??臻g,若遞歸深度過(guò)深易導(dǎo)致棧溢出;重復(fù)計(jì)算問(wèn)題(如斐波那契數(shù)列的簡(jiǎn)單遞歸實(shí)現(xiàn),會(huì)重復(fù)計(jì)算大量相同子問(wèn)題),效率較低。
優(yōu)化方案:
尾遞歸優(yōu)化:將遞歸調(diào)用放在函數(shù)的最后一步(尾調(diào)用),部分語(yǔ)言(如ES6規(guī)范中的JavaScript)支持尾遞歸優(yōu)化,可避免棧溢出(但實(shí)際瀏覽器支持度有限);
記憶化緩存:將已計(jì)算的子問(wèn)題結(jié)果緩存起來(lái),避免重復(fù)計(jì)算(如用對(duì)象存儲(chǔ)斐波那契數(shù)列的已計(jì)算值);
迭代改寫(xiě):將遞歸邏輯改為循環(huán)迭代(如用for循環(huán)計(jì)算階乘),完全避免遞歸調(diào)用的??臻g占用。
十. 快速排序的邏輯是什么?
快速排序是一種高效的排序算法,基于分治思想,核心邏輯是通過(guò)“選基準(zhǔn)、分區(qū)、遞歸排序”三步,將無(wú)序數(shù)組逐步拆解為有序子數(shù)組,最終合并為完整的有序數(shù)組,其時(shí)間復(fù)雜度平均為O(n log n),最壞為O(n²)(可通過(guò)合理選基準(zhǔn)優(yōu)化),具體邏輯步驟如下:
步驟1:選擇基準(zhǔn)元素(pivot):從待排序數(shù)組中選擇一個(gè)元素作為“基準(zhǔn)”,基準(zhǔn)的選擇直接影響排序效率,常見(jiàn)選擇方式有:
選數(shù)組第一個(gè)元素或最后一個(gè)元素(簡(jiǎn)單但易導(dǎo)致最壞情況,如有序數(shù)組);
選數(shù)組中間元素(折中方案);
隨機(jī)選擇元素(推薦,可降低最壞情況概率)。
步驟2:分區(qū)操作(partition):以基準(zhǔn)元素為標(biāo)準(zhǔn),將待排序數(shù)組劃分為兩個(gè)子數(shù)組: 分區(qū)實(shí)現(xiàn)邏輯(雙指針?lè)ǎ?/p>
左子數(shù)組:所有元素都小于基準(zhǔn)元素;
右子數(shù)組:所有元素都大于或等于基準(zhǔn)元素;
基準(zhǔn)元素最終會(huì)落在其“正確的排序位置”(即最終有序數(shù)組中該元素的位置)。
初始化左指針(left)指向數(shù)組起始位置,右指針(right)指向數(shù)組末尾;
右指針向左移動(dòng),找到第一個(gè)小于基準(zhǔn)的元素,停止移動(dòng);
左指針向右移動(dòng),找到第一個(gè)大于或等于基準(zhǔn)的元素,停止移動(dòng);
交換左、右指針指向的元素;
重復(fù)步驟2-4,直到左指針 >= 右指針;
交換基準(zhǔn)元素與左指針(或右指針)指向的元素,完成分區(qū),此時(shí)基準(zhǔn)元素位于正確位置。
步驟3:遞歸排序子數(shù)組:對(duì)分區(qū)后的左子數(shù)組和右子數(shù)組,分別重復(fù)步驟1-2(選基準(zhǔn)、分區(qū)),直到子數(shù)組的長(zhǎng)度為0或1(此時(shí)子數(shù)組已天然有序,無(wú)需繼續(xù)排序)。
步驟4:合并結(jié)果:由于左子數(shù)組、基準(zhǔn)元素、右子數(shù)組已分別有序,將三者直接拼接即可得到完整的有序數(shù)組(遞歸過(guò)程中無(wú)需額外合并操作,分區(qū)后自然有序)。
示例(以數(shù)組[5,2,9,3,7,6,1]為例):
選基準(zhǔn):假設(shè)選中間元素3;
分區(qū):通過(guò)雙指針交換,最終得到左子數(shù)組[2,1]、基準(zhǔn)3、右子數(shù)組[5,9,7,6];
遞歸排序左子數(shù)組[2,1]:選基準(zhǔn)2,分區(qū)得到[1]、2、空數(shù)組,左子數(shù)組排序完成;
遞歸排序右子數(shù)組[5,9,7,6]:選基準(zhǔn)7,分區(qū)得到[5,6]、7、[9];再遞歸排序[5,6],得到[5,6];
拼接結(jié)果:[1,2] + [3] + [5,6,7,9] → 最終有序數(shù)組[1,2,3,5,6,7,9]。
核心特點(diǎn):
原地排序:不需要額外的大量存儲(chǔ)空間(僅遞歸調(diào)用占用??臻g),空間復(fù)雜度為O(log n)(遞歸深度);
不穩(wěn)定排序:相等元素的相對(duì)位置可能在排序過(guò)程中改變(如數(shù)組[3,2,3,1],排序后兩個(gè)3的位置可能顛倒);
高效性:平均時(shí)間復(fù)雜度O(n log n),是實(shí)際開(kāi)發(fā)中最常用的排序算法之一(如V8引擎的Array.sort()在數(shù)組長(zhǎng)度大于22時(shí)使用快速排序的變體)。
總結(jié)
到此這篇關(guān)于JS核心知識(shí)點(diǎn)之箭頭函數(shù)與this詳細(xì)解析的文章就介紹到這了,更多相關(guān)JS箭頭函數(shù)與this內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS 箭頭函數(shù)的this指向詳解
- JavaScript箭頭函數(shù)中的this詳解
- 深入理解Javascript箭頭函數(shù)中的this
- JS中箭頭函數(shù)與this的寫(xiě)法和理解
- JavaScript基礎(chǔ)之this和箭頭函數(shù)詳析
- JS函數(shù)(普通函數(shù),箭頭函數(shù))中this的指向問(wèn)題詳解
- 一篇文章詳細(xì)講解JavaScript中的this(普通函數(shù)、箭頭函數(shù)、?函數(shù)運(yùn)用)
- JavaScript改變this指向的四種方法(bind、call、apply 和箭頭函數(shù))
相關(guān)文章
Javascript remove 自定義數(shù)組刪除方法
Javascript自定義數(shù)組刪除方法remove(),需要的朋友可以參考下。2009-10-10
一行JavaScript代碼如何實(shí)現(xiàn)瀑布流布局
這篇文章主要給大家介紹了如何通過(guò)一行JavaScript代碼實(shí)現(xiàn)瀑布流布局的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
javascript實(shí)現(xiàn)簡(jiǎn)單的ajax封裝示例
這篇文章主要介紹了javascript實(shí)現(xiàn)簡(jiǎn)單的ajax封裝功能,結(jié)合實(shí)例形式分析了ajax基本功能與操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-12-12
判斷字符串的長(zhǎng)度(優(yōu)化版)中文占兩個(gè)字符
判斷字符串的長(zhǎng)度的方法有很多,本例介紹的是優(yōu)化之前的方法,記住中文占兩個(gè)字符,需要的朋友不要錯(cuò)過(guò)2014-10-10
前端實(shí)現(xiàn)json動(dòng)畫(huà)詳細(xì)過(guò)程(附帶示例)
這篇文章主要介紹了如何使用Lottie制作動(dòng)畫(huà),包括創(chuàng)建動(dòng)畫(huà)文件.json、實(shí)現(xiàn)效果、在Git倉(cāng)庫(kù)中保存和共享、運(yùn)行動(dòng)畫(huà)以及在動(dòng)畫(huà)天堂下載和顯示JSON動(dòng)畫(huà),文中通過(guò)代碼及圖文介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
TypeScript類型系統(tǒng)自定義數(shù)據(jù)類型教程示例
這篇文章主要為大家介紹了TypeScript類型系統(tǒng)自定義數(shù)據(jù)類型教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
JavaScript統(tǒng)計(jì)字符出現(xiàn)次數(shù)
這篇文章主要為大家詳細(xì)介紹了JavaScript字符統(tǒng)計(jì)出現(xiàn)次數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03

