1、項(xiàng)目中亮點(diǎn)(難點(diǎn))
在項(xiàng)目中用ECharts畫的可視化大屏的時(shí)候,里面的字體在調(diào)整瀏覽器大小的時(shí)候無(wú)法做到適配,然后經(jīng)過到處查到處問才用css3的方法寫出來
2、移動(dòng)端適配方案
移動(dòng)端適配是指將網(wǎng)頁(yè)或應(yīng)用程序的布局、樣式和功能調(diào)整到不同移動(dòng)設(shè)備上以獲得更好的用戶體驗(yàn)。以下是一些移動(dòng)端適配的常用方法:
1、響應(yīng)式設(shè)計(jì)(Responsive Design):使用CSS媒體查詢和流式布局,根據(jù)設(shè)備的屏幕大小和分辨率自動(dòng)調(diào)整頁(yè)面布局和元素的大小。
2、流式布局(Fluid Layout):使用百分比寬度代替固定像素寬度,使頁(yè)面可以根據(jù)設(shè)備屏幕的大小進(jìn)行自適應(yīng)。
3、彈性盒子布局(Flexbox Layout):使用CSS彈性盒子模型來實(shí)現(xiàn)靈活的布局,可以根據(jù)設(shè)備屏幕的大小和方向自動(dòng)調(diào)整元素的位置和大小。
4、視口設(shè)置(Viewport Setting):通過設(shè)置視口標(biāo)簽(viewport meta tag)來控制頁(yè)面在移動(dòng)設(shè)備上的顯示,例如設(shè)置縮放、寬度等參數(shù)。
5、圖片適配:使用CSS媒體查詢和srcset屬性,根據(jù)設(shè)備的像素密度(DPR)加載適合的圖片,以提高頁(yè)面加載速度和顯示質(zhì)量。
6、觸摸事件與手勢(shì)支持:使用相應(yīng)的JavaScript庫(kù)和API來處理移動(dòng)設(shè)備上的觸摸事件和手勢(shì)操作,以提供更好的用戶交互體驗(yàn)。
7、移動(dòng)設(shè)備優(yōu)先(Mobile-first):在開發(fā)過程中首先考慮移動(dòng)設(shè)備的布局和功能,然后再逐步增加適配桌面設(shè)備的樣式和功能。
需要注意的是,移動(dòng)端適配并非一勞永逸的解決方案,因?yàn)椴煌囊苿?dòng)設(shè)備和屏幕尺寸仍然存在差異。因此,在進(jìn)行移動(dòng)端適配時(shí),應(yīng)該綜合考慮不同設(shè)備的特點(diǎn),并進(jìn)行測(cè)試和調(diào)整以確保良好的用戶體驗(yàn)。
3、移動(dòng)端適配方案
移動(dòng)端適配有多種方案可供選擇,以下是一些常用的方案:
1、響應(yīng)式設(shè)計(jì)(Responsive Design):使用CSS媒體查詢和流式布局,根據(jù)設(shè)備的屏幕大小和分辨率自動(dòng)調(diào)整頁(yè)面布局和元素的大小。這種方案可以適配各種移動(dòng)設(shè)備,并且只需要維護(hù)一個(gè)代碼庫(kù)。
2、動(dòng)態(tài)REM適配:使用JavaScript動(dòng)態(tài)計(jì)算根元素的字體大?。╮em),然后使用rem作為長(zhǎng)度單位進(jìn)行布局。通過設(shè)置不同的根字體大小,可以根據(jù)設(shè)備屏幕的寬度來動(dòng)態(tài)調(diào)整頁(yè)面的布局和元素的大小。
3、視口設(shè)置(Viewport Setting):通過設(shè)置視口標(biāo)簽(viewport meta tag)來控制頁(yè)面在移動(dòng)設(shè)備上的顯示??梢允褂胕nitial-scale屬性設(shè)置初始縮放比例,width屬性設(shè)置視口寬度,以及其他屬性來控制各種適配效果。
4、CSS Flexbox布局:使用CSS彈性盒子模型(Flexbox)來實(shí)現(xiàn)靈活的布局。Flexbox可以自動(dòng)調(diào)整元素的位置和大小,適應(yīng)不同屏幕尺寸的設(shè)備。
5、CSS Grid布局:使用CSS網(wǎng)格布局(Grid)來創(chuàng)建復(fù)雜的網(wǎng)格結(jié)構(gòu),以實(shí)現(xiàn)精確的布局控制。CSS Grid允許將頁(yè)面劃分為行和列,可以根據(jù)不同屏幕尺寸來調(diào)整布局。
6、CSS媒體查詢(Media Queries):使用CSS媒體查詢來根據(jù)設(shè)備的特性和屏幕尺寸應(yīng)用不同的樣式規(guī)則??梢愿鶕?jù)需要設(shè)置不同的斷點(diǎn)(breakpoint),在不同屏幕寬度下應(yīng)用不同的樣式。
7、圖片適配:使用CSS媒體查詢和srcset屬性,根據(jù)設(shè)備的像素密度(DPR)加載適合的圖片,以提高頁(yè)面加載速度和顯示質(zhì)量。
這些方案可以單獨(dú)使用或結(jié)合使用,具體選擇哪種方案取決于項(xiàng)目需求、開發(fā)技術(shù)和團(tuán)隊(duì)偏好。在進(jìn)行移動(dòng)端適配時(shí),還需要進(jìn)行測(cè)試和調(diào)整以確保最佳的用戶體驗(yàn)。
4、rem和em的區(qū)別
rem(root em)和em(relative em)是兩種相對(duì)長(zhǎng)度單位,它們之間的區(qū)別在于相對(duì)于哪個(gè)元素來進(jìn)行計(jì)算。
em 單位:em 單位是相對(duì)于父元素的字體大小來計(jì)算的。例如,如果一個(gè)元素的字體大小設(shè)置為 1.5em,那么它的大小將是父元素字體大小的1.5倍。如果沒有明確指定父元素的字體大小,則默認(rèn)相對(duì)于父元素的字體大小。這意味著 em 單位是可以繼承的,會(huì)受到父元素字體大小的影響。
rem 單位:rem 單位是相對(duì)于根元素(html 元素)的字體大小來計(jì)算的。與 em 單位不同,rem 單位的計(jì)算不會(huì)受到父元素字體大小的影響。假設(shè)根元素的字體大小為 16px,那么 1rem 就等于 16px。無(wú)論元素嵌套在哪個(gè)層級(jí),rem 單位都是相對(duì)于根元素的字體大小進(jìn)行計(jì)算。
因此,rem 單位更適合用于移動(dòng)端適配,因?yàn)樗某叽绮粫?huì)受到父元素字體大小的影響,可以更準(zhǔn)確地實(shí)現(xiàn)響應(yīng)式布局和適配效果。而 em 單位則更適合用于相對(duì)于父元素的字體大小進(jìn)行計(jì)算的場(chǎng)景,如文字大小和行高等。
需要注意的是,無(wú)論是 rem 還是 em 單位,在實(shí)際使用中都需要結(jié)合媒體查詢和根元素的字體大小動(dòng)態(tài)調(diào)整來實(shí)現(xiàn)移動(dòng)端適配的效果。
5、?優(yōu)化網(wǎng)頁(yè)性能的技術(shù)有哪些
優(yōu)化網(wǎng)頁(yè)性能是提高用戶體驗(yàn)和頁(yè)面加載速度的重要方面。以下是一些常用的優(yōu)化網(wǎng)頁(yè)性能的技術(shù):
1、圖片優(yōu)化:使用適當(dāng)?shù)膱D片格式(如 WebP)、壓縮圖片大小、懶加載圖片、使用 CSS sprites 或 SVG 精靈圖等減少 HTTP 請(qǐng)求次數(shù)和加快圖片加載速度。
2、文件壓縮:壓縮 HTML、CSS 和 JavaScript 文件,減小文件大小,從而減少加載時(shí)間。
3、使用 CDN(內(nèi)容分發(fā)網(wǎng)絡(luò)):將靜態(tài)資源存儲(chǔ)在全球各地的 CDN 節(jié)點(diǎn)上,加速資源加載速度。
4、減少 HTTP 請(qǐng)求:合并 CSS 和 JavaScript 文件、使用字體圖標(biāo)代替圖片、減少頁(yè)面元素?cái)?shù)量等方式來減少 HTTP 請(qǐng)求次數(shù)。
5、使用異步加載:將不影響頁(yè)面渲染的資源(如廣告、統(tǒng)計(jì)代碼)設(shè)置為異步加載,避免阻塞頁(yè)面渲染。
6、延遲加載資源:使用懶加載技術(shù)延遲加載圖片、視頻等資源,根據(jù)用戶需求動(dòng)態(tài)加載內(nèi)容。
7、緩存優(yōu)化:設(shè)置合適的緩存策略(如設(shè)置緩存頭、使用瀏覽器緩存等),減少重復(fù)下載相同資源。
8、壓縮傳輸數(shù)據(jù):使用 GZIP 壓縮傳輸數(shù)據(jù),減小文件大小,加快數(shù)據(jù)傳輸速度。
9、使用預(yù)加載和預(yù)渲染:利用<link rel="preload">預(yù)加載關(guān)鍵資源、使用<link rel="prerender">預(yù)渲染關(guān)鍵頁(yè)面等技術(shù)來提前加載資源和頁(yè)面,加速用戶訪問速度。
10、優(yōu)化 CSS 和 JavaScript:減少不必要的 CSS 樣式和 JavaScript 代碼、避免過多的重繪和回流操作、優(yōu)化代碼結(jié)構(gòu)等來提高代碼執(zhí)行效率。
這些技術(shù)可以結(jié)合使用,根據(jù)具體情況和需求來優(yōu)化網(wǎng)頁(yè)性能,提升用戶體驗(yàn),加快頁(yè)面加載速度。
6、 小程序項(xiàng)目?jī)?yōu)化性能的技術(shù)有哪些
小程序項(xiàng)目的性能優(yōu)化同樣非常重要,可以提升用戶體驗(yàn)和降低應(yīng)用的資源消耗。以下是一些優(yōu)化小程序項(xiàng)目性能的技術(shù):
1、減少 HTTP 請(qǐng)求次數(shù):合并請(qǐng)求、減少資源文件大小、使用 CDN 加速等方式來減少網(wǎng)絡(luò)請(qǐng)求次數(shù)。
2、使用分包加載:將小程序的功能模塊分包,按需加載,避免一次性加載過多的資源影響頁(yè)面加載速度。
3、圖片優(yōu)化:壓縮圖片大小、使用合適的圖片格式、懶加載圖片等方式來減小圖片對(duì)性能的影響。
4、使用 setData 優(yōu)化渲染:避免頻繁調(diào)用 setData 方法,可以合并數(shù)據(jù)更新操作,減少渲染次數(shù)。
5、使用 WXS:盡量使用 WXS(小程序原生腳本語(yǔ)言)替代 JavaScript,提高性能。
6、避免不必要的動(dòng)畫和過渡效果:過多的動(dòng)畫和過渡效果會(huì)增加頁(yè)面的渲染負(fù)擔(dān),盡量減少不必要的動(dòng)效。
7、使用 wx.requestTask 控制并發(fā)請(qǐng)求:通過 wx.requestTask 控制并發(fā)請(qǐng)求的數(shù)量,避免同時(shí)發(fā)送大量請(qǐng)求導(dǎo)致性能下降。
8、合理設(shè)置頁(yè)面參數(shù):合理設(shè)置頁(yè)面參數(shù),如設(shè)置頁(yè)面背景色、標(biāo)題欄顏色等,以減少頁(yè)面渲染時(shí)間。
9、避免在 Page 生命周期鉤子中做過多耗時(shí)操作:盡量避免在頁(yè)面的生命周期鉤子函數(shù)中進(jìn)行過多的耗時(shí)操作,可以在 onLoad 階段做一些初始化工作,避免影響頁(yè)面展示速度。
10、使用云開發(fā):如果需要后端支持,可以考慮使用小程序云開發(fā),減少對(duì)服務(wù)器的依賴,提高小程序的性能和穩(wěn)定性。
通過以上技術(shù)手段的綜合應(yīng)用,可以有效優(yōu)化小程序項(xiàng)目的性能,提升用戶體驗(yàn),降低資源消耗。
7、防抖和節(jié)流區(qū)別
防抖(Debouncing)和節(jié)流(Throttling)都是用于限制某個(gè)函數(shù)的執(zhí)行頻率,以優(yōu)化性能和用戶體驗(yàn)的常用技術(shù)。它們的區(qū)別在于觸發(fā)執(zhí)行的時(shí)機(jī)不同:
1、防抖(Debouncing):
當(dāng)事件被觸發(fā)后,如果在指定的延遲時(shí)間內(nèi)沒有再次觸發(fā)該事件,那么才會(huì)執(zhí)行相應(yīng)的操作。
也就是說,如果連續(xù)觸發(fā)同一個(gè)事件,只有在事件停止觸發(fā)一段時(shí)間后才會(huì)執(zhí)行對(duì)應(yīng)的操作。
示例場(chǎng)景:輸入框搜索建議。用戶在輸入框中不斷輸入內(nèi)容,但我們希望等用戶停止輸入一小段時(shí)間后再發(fā)起搜索請(qǐng)求,以減少不必要的網(wǎng)絡(luò)請(qǐng)求。
2、節(jié)流(Throttling):
無(wú)論事件觸發(fā)頻率多高,每隔一定的時(shí)間就會(huì)執(zhí)行一次相應(yīng)的操作。
即使在間隔時(shí)間內(nèi)事件不斷觸發(fā),也只會(huì)每隔一段時(shí)間執(zhí)行一次操作。
示例場(chǎng)景:滾動(dòng)加載。當(dāng)用戶滾動(dòng)頁(yè)面時(shí),我們可能希望每隔一定時(shí)間才觸發(fā)一次加載更多的數(shù)據(jù),而不是用戶不斷滾動(dòng)就不斷觸發(fā)加載操作。
總的來說,防抖適合處理頻繁觸發(fā)但我們只關(guān)心最后一次觸發(fā)的情況,而節(jié)流適合處理高頻觸發(fā)但我們希望控制執(zhí)行頻率的情況。在實(shí)際開發(fā)中,根據(jù)具體的業(yè)務(wù)需求和場(chǎng)景來選擇使用防抖或節(jié)流來優(yōu)化性能。
8、深淺拷貝淺拷貝理解區(qū)別
深拷貝(Deep Copy)和淺拷貝(Shallow Copy)是在編程中經(jīng)常遇到的概念,它們之間的區(qū)別在于拷貝的對(duì)象的層次不同:
1、淺拷貝(Shallow Copy):
淺拷貝是指只復(fù)制對(duì)象本身,而不復(fù)制對(duì)象內(nèi)部的引用類型的數(shù)據(jù)。
當(dāng)進(jìn)行淺拷貝時(shí),新對(duì)象會(huì)引用原始對(duì)象中的引用類型的數(shù)據(jù),如果修改了新對(duì)象中的引用類型數(shù)據(jù),原始對(duì)象中的數(shù)據(jù)也會(huì)被修改。
淺拷貝通常只復(fù)制對(duì)象的第一層數(shù)據(jù),而不會(huì)遞歸復(fù)制對(duì)象內(nèi)部的引用類型數(shù)據(jù)。
示例:使用Object.assign()、擴(kuò)展運(yùn)算符...或Array.slice()等方法執(zhí)行的拷貝操作通常是淺拷貝。
2、深拷貝(Deep Copy):
深拷貝是指完全復(fù)制一個(gè)對(duì)象,包括對(duì)象本身以及對(duì)象內(nèi)部所有的引用類型數(shù)據(jù)。
在進(jìn)行深拷貝時(shí),會(huì)遞歸復(fù)制對(duì)象內(nèi)部的所有引用類型數(shù)據(jù),保證新對(duì)象與原始對(duì)象完全獨(dú)立,互不影響。
深拷貝會(huì)創(chuàng)建一個(gè)全新的對(duì)象,而不是簡(jiǎn)單地引用原始對(duì)象的數(shù)據(jù)。
示例:通過遞歸復(fù)制對(duì)象的所有屬性和嵌套對(duì)象,或者使用第三方庫(kù)如lodash的_.cloneDeep()方法可以實(shí)現(xiàn)深拷貝。
在實(shí)際編程中,需要根據(jù)具體情況來選擇使用淺拷貝還是深拷貝。如果對(duì)象的數(shù)據(jù)結(jié)構(gòu)比較簡(jiǎn)單且沒有嵌套引用類型數(shù)據(jù),可以使用淺拷貝;如果對(duì)象數(shù)據(jù)結(jié)構(gòu)復(fù)雜、包含嵌套引用類型數(shù)據(jù),需要保持獨(dú)立性,則應(yīng)該使用深拷貝。
9、數(shù)組常用的方法
數(shù)組在 JavaScript 中是一種常用的數(shù)據(jù)結(jié)構(gòu),有許多內(nèi)置方法可以對(duì)數(shù)組進(jìn)行操作和處理。以下是一些常用的數(shù)組方法:
push():向數(shù)組末尾添加一個(gè)或多個(gè)元素,并返回新的長(zhǎng)度。
pop():刪除并返回?cái)?shù)組的最后一個(gè)元素。
shift():刪除并返回?cái)?shù)組的第一個(gè)元素。
unshift():向數(shù)組開頭添加一個(gè)或多個(gè)元素,并返回新的長(zhǎng)度。
splice():從數(shù)組中添加/刪除項(xiàng)目,可以實(shí)現(xiàn)刪除、替換、插入等操作。
slice():返回?cái)?shù)組的一部分,不修改原數(shù)組。
concat():連接兩個(gè)或多個(gè)數(shù)組,并返回新數(shù)組。
forEach():對(duì)數(shù)組中的每個(gè)元素執(zhí)行指定操作。
map():對(duì)數(shù)組的每個(gè)元素都執(zhí)行指定操作,并返回一個(gè)新數(shù)組。
filter():根據(jù)指定函數(shù)篩選出符合條件的數(shù)組元素,并返回一個(gè)新數(shù)組。
find():返回符合條件的第一個(gè)數(shù)組元素,沒有找到則返回 undefined。
indexOf()?和?lastIndexOf():返回指定元素在數(shù)組中的位置(從前往后或從后往前搜索)。
includes():判斷數(shù)組是否包含某個(gè)特定的元素,返回?true?或?false。
reduce()?和?reduceRight():從左到右或從右到左依次對(duì)數(shù)組元素進(jìn)行累加操作。
這些只是常用的一部分?jǐn)?shù)組方法,JavaScript 中還有許多其他數(shù)組方法可供使用。通過熟練掌握這些數(shù)組方法,可以更高效地對(duì)數(shù)組進(jìn)行各種操作和處理。
10、計(jì)算一個(gè)數(shù)組的總和有哪些方法
1、計(jì)算一個(gè)數(shù)組的總和可以使用多種方法,下面列舉了一些常見的計(jì)算數(shù)組總和的方法:
使用循環(huán)遍歷數(shù)組累加:
let arr = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < arr.length; i++) {
? ? sum += arr[i];
}console.log(sum); // 輸出:15
2、使用數(shù)組的reduce()方法:
let arr = [1, 2, 3, 4, 5];let sum = arr.reduce((acc, curr) => acc + curr, 0);console.log(sum); // 輸出:15
3、使用forEach()方法遍歷數(shù)組并累加:
let arr = [1, 2, 3, 4, 5];let sum = 0;
arr.forEach(num=> {
? ? sum += num;
});console.log(sum); // 輸出:15
4、使用eval()函數(shù)(不推薦,存在安全風(fēng)險(xiǎn)):
let arr = [1, 2, 3, 4, 5];let sum = eval(arr.join('+'));console.log(sum); // 輸出:15
5、使用遞歸實(shí)現(xiàn)求和:
function calculateSum(arr, index) {
? ? if (index === arr.length) {
? ? ? ? return 0;
? ? }
? ? return arr[index] + calculateSum(arr, index + 1);
}let arr = [1, 2, 3, 4, 5];let sum = calculateSum(arr, 0);console.log(sum); // 輸出:15
這些都是計(jì)算數(shù)組總和的常見方法,根據(jù)實(shí)際情況選擇適合自己需求的方法。其中,使用reduce()方法是比較簡(jiǎn)潔和高效的方式來計(jì)算數(shù)組的總和。
11、 find,findindex方法
find()和findIndex()是 JavaScript 數(shù)組方法,用于在數(shù)組中查找元素,它們的區(qū)別在于返回值不同:
1、find()方法:
find()?方法用于找到第一個(gè)滿足條件的數(shù)組元素,并返回該元素的值。
如果找到符合條件的元素,則返回該元素的值;如果沒有找到,則返回?undefined。
示例:
let arr = [5, 12, 8, 130, 44];let found = arr.find(element=> element > 10);console.log(found); // 輸出:12
2、findIndex()方法:
findIndex()?方法用于找到第一個(gè)滿足條件的數(shù)組元素,并返回該元素的索引。
如果找到符合條件的元素,則返回該元素的索引;如果沒有找到,則返回?-1。
示例:
let arr = [5, 12, 8, 130, 44];let foundIndex = arr.findIndex(element=> element > 10);console.log(foundIndex); // 輸出:1
因此,find()方法返回滿足條件的元素的值,而findIndex()方法返回滿足條件的元素的索引。根據(jù)具體需求,可以選擇使用這兩個(gè)方法來對(duì)數(shù)組進(jìn)行查找操作。
12、JS事件循環(huán)機(jī)制
JavaScript 的事件循環(huán)機(jī)制是為了處理異步操作和事件回調(diào)而設(shè)計(jì)的執(zhí)行模型。它基于單線程的特點(diǎn),通過事件循環(huán)來管理任務(wù)隊(duì)列,使得 JavaScript 可以處理并發(fā)的異步操作。
事件循環(huán)機(jī)制主要包含以下幾個(gè)組件:
1、任務(wù)隊(duì)列(Task Queue):
任務(wù)隊(duì)列用于存儲(chǔ)待執(zhí)行的任務(wù),包括同步任務(wù)和異步任務(wù)。
同步任務(wù)會(huì)立即執(zhí)行,而異步任務(wù)會(huì)先被放入任務(wù)隊(duì)列中,等待執(zhí)行時(shí)機(jī)。
2、事件觸發(fā)器(Event Trigger):
事件觸發(fā)器用于監(jiān)測(cè)是否有需要處理的事件,比如用戶交互、定時(shí)器到期、網(wǎng)絡(luò)請(qǐng)求完成等。
當(dāng)事件觸發(fā)時(shí),相應(yīng)的回調(diào)函數(shù)會(huì)被放入任務(wù)隊(duì)列中。
3、事件循環(huán)(Event Loop):
事件循環(huán)是一個(gè)持續(xù)運(yùn)行的過程,不斷地從任務(wù)隊(duì)列中取出任務(wù)并執(zhí)行。
執(zhí)行過程中會(huì)根據(jù)任務(wù)的類型進(jìn)行處理,同步任務(wù)會(huì)立即執(zhí)行,而異步任務(wù)則會(huì)等待合適的時(shí)機(jī)執(zhí)行。
事件循環(huán)的執(zhí)行順序如下:
1、執(zhí)行同步任務(wù)直到執(zhí)行棧為空。
2、如果存在微任務(wù)(Promise、MutationObserver 等),則依次執(zhí)行所有微任務(wù)。
3、執(zhí)行渲染操作,更新界面。
4、檢查是否有 Web Worker 任務(wù)。
5、執(zhí)行下一輪的事件循環(huán),從任務(wù)隊(duì)列中取出一個(gè)宏任務(wù)執(zhí)行。如果沒有宏任務(wù),則等待新的事件觸發(fā)。
6、返回第 1 步。
可以簡(jiǎn)單理解為,每一輪事件循環(huán)會(huì)先處理所有的微任務(wù),然后執(zhí)行一個(gè)宏任務(wù)(可能是異步任務(wù)),然后進(jìn)行渲染操作,再進(jìn)行下一輪事件循環(huán)。
需要注意的是,當(dāng)任務(wù)隊(duì)列中存在大量的同步任務(wù)時(shí),會(huì)阻塞主線程的執(zhí)行,造成頁(yè)面卡頓。因此,在編寫 JavaScript 代碼時(shí),應(yīng)盡量將耗時(shí)的操作放入異步任務(wù)中,以充分利用事件循環(huán)機(jī)制,提高頁(yè)面的響應(yīng)性能。
13、冒泡排序的寫法
冒泡排序是一種簡(jiǎn)單的排序算法,它重復(fù)地遍歷要排序的列表,比較每對(duì)相鄰的元素,并交換順序錯(cuò)誤的元素。重復(fù)這個(gè)過程直到?jīng)]有需要交換的元素,也就是列表已經(jīng)排序完成。以下是冒泡排序的基本寫法:
function bubbleSort(arr) {
? ? let len = arr.length;
? ? for (let i = 0; i < len - 1; i++) {
? ? ? ? for (let j = 0; j < len - 1 - i; j++) {
? ? ? ? ? ? if (arr[j] > arr[j + 1]) {
? ? ? ? ? ? ? ? // 交換 arr[j] 和 arr[j+1]? ? ? ? ? ? ? ? let temp = arr[j];
? ? ? ? ? ? ? ? arr[j] = arr[j + 1];
? ? ? ? ? ? ? ? arr[j + 1] = temp;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return arr;
}
在冒泡排序算法中,主要涉及的屬性包括:
1、數(shù)組長(zhǎng)度(len):需要排序的數(shù)組的長(zhǎng)度。
2、外層循環(huán)中的索引(i):用于控制比較的輪數(shù)。在每一輪中,都會(huì)將當(dāng)前最大(或最?。┑脑匾苿?dòng)到正確的位置。
3、內(nèi)層循環(huán)中的索引(j):用于比較相鄰的元素,并交換它們的位置。
理解冒泡排序的關(guān)鍵點(diǎn)在于它的工作原理:
1、外層循環(huán)控制了比較的輪數(shù),每一輪都會(huì)找到當(dāng)前未排序部分中的最大(或最?。┰夭阉诺秸_的位置。
2、內(nèi)層循環(huán)通過比較相鄰的元素,并根據(jù)需要交換它們的位置,逐漸將大(或?。┑脑亍懊芭荨钡綌?shù)組的末尾。
3、冒泡排序雖然簡(jiǎn)單,但對(duì)于小型數(shù)據(jù)集來說是一個(gè)有效且容易實(shí)現(xiàn)的排序算法。然而,由于其時(shí)間復(fù)雜度為 O(n^2),因此在大型數(shù)據(jù)集上性能較差,不適合大規(guī)模數(shù)據(jù)的排序操作。
14、 說一說promise
Promise 在 JavaScript 中起到了處理異步操作的重要作用,用于處理異步操作的一種對(duì)象它代表了一個(gè)異步操作的最終完成或失敗,以及其結(jié)果值。
Promise 對(duì)象有三種狀態(tài):
1、Pending(進(jìn)行中):初始狀態(tài),表示異步操作尚未完成,也沒有失敗。
2、Fulfilled(已成功):表示異步操作成功完成,并且有一個(gè)值作為結(jié)果。
3、Rejected(已失?。?/b>:表示異步操作失敗,并且有一個(gè)原因(錯(cuò)誤)作為結(jié)果。
Promise 構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),這個(gè)函數(shù)又接受兩個(gè)參數(shù):resolve 和 reject,它們是兩個(gè)函數(shù)。在異步操作成功時(shí)調(diào)用 resolve,傳遞操作的結(jié)果;在異步操作失敗時(shí)調(diào)用 reject,傳遞失敗的原因。
通過使用 Promise,可以更好地處理異步操作,避免回調(diào)地獄(callback hell),使代碼結(jié)構(gòu)清晰,易于理解和維護(hù)。
Promise 在 JavaScript 中起到了處理異步操作的重要作用。它的主要功能包括:
1、簡(jiǎn)化異步操作:Promise 可以讓我們更容易地執(zhí)行和管理異步操作。通過 Promise,可以將異步代碼組織成較為線性和清晰的結(jié)構(gòu),而不是嵌套多層回調(diào)函數(shù)(回調(diào)地獄)。
2、提供更清晰的異步流程控制:通過 Promise 的狀態(tài)和狀態(tài)轉(zhuǎn)換機(jī)制,我們可以更好地控制異步操作的執(zhí)行流程。Promise 可以處于 pending、fulfilled 或 rejected 三種狀態(tài)之一,這種明確的狀態(tài)機(jī)制有助于編寫更可靠的異步代碼。
3、處理異步操作的成功和失敗:通過 Promise 的 resolve 和 reject 方法,我們可以清晰地處理異步操作成功和失敗時(shí)的情況,并分別執(zhí)行相應(yīng)的邏輯。
4、鏈?zhǔn)秸{(diào)用:Promise 支持鏈?zhǔn)秸{(diào)用,使得多個(gè)異步操作可以按順序執(zhí)行,并且很容易處理它們之間的依賴關(guān)系。
5、異常處理:Promise 提供了 catch 方法用于捕獲異步操作中的異常,使得錯(cuò)誤處理變得更加方便。
總之,Promise 干了許多事情,其中最重要的作用是簡(jiǎn)化和改善了 JavaScript 中的異步編程,使得代碼更加清晰、可讀性更強(qiáng),同時(shí)也提高了異步操作的可靠性和可維護(hù)性。希望這能夠幫助你更好地理解 Promise 在 JavaScript 中的作用!如果有其他問題,也歡迎隨時(shí)提出。
15、async和await(同步和異步)的理解和區(qū)別
同步和異步是兩種不同的任務(wù)執(zhí)行方式,它們的理解和區(qū)別如下:
1、同步(Synchronous):
同步任務(wù)按照順序執(zhí)行,每個(gè)任務(wù)必須等待上一個(gè)任務(wù)執(zhí)行完成后才能繼續(xù)執(zhí)行。
在同步任務(wù)執(zhí)行過程中,程序會(huì)阻塞,即代碼執(zhí)行時(shí)會(huì)停止其他操作的進(jìn)行,直到當(dāng)前任務(wù)完成。
同步任務(wù)通常是可預(yù)測(cè)的,可以按照固定的順序和時(shí)間完成。
2、異步(Asynchronous):
異步任務(wù)不按照順序依次執(zhí)行,可以同時(shí)執(zhí)行多個(gè)任務(wù),任務(wù)之間相互獨(dú)立。
在異步任務(wù)執(zhí)行過程中,程序不會(huì)等待任務(wù)完成,而是繼續(xù)執(zhí)行后續(xù)代碼。異步任務(wù)通常會(huì)在后臺(tái)或另外的線程中執(zhí)行。
異步任務(wù)通常是不可預(yù)測(cè)的,其執(zhí)行時(shí)間和順序可能受到外部因素的影響。
異步任務(wù)通常采用回調(diào)函數(shù)、Promise、async/await 等機(jī)制來處理異步操作的結(jié)果。
3、區(qū)別:
同步任務(wù)是按照順序依次執(zhí)行的,而異步任務(wù)則是在后臺(tái)或其他線程中執(zhí)行,并且不會(huì)阻塞后續(xù)代碼的執(zhí)行。
同步任務(wù)的執(zhí)行時(shí)間和順序是可預(yù)測(cè)的,而異步任務(wù)的執(zhí)行時(shí)間和順序是不確定的。
同步任務(wù)適合處理簡(jiǎn)單的、順序執(zhí)行的操作,而異步任務(wù)適合處理復(fù)雜的、依賴外部資源或需要長(zhǎng)時(shí)間處理的操作。
在實(shí)際編程中,異步編程非常重要,特別是在處理網(wǎng)絡(luò)請(qǐng)求、文件操作、定時(shí)任務(wù)等場(chǎng)景下。通過使用異步方式,可以避免阻塞主線程,提高程序的響應(yīng)性能和用戶體驗(yàn)。
希望這個(gè)解答能夠幫助你更好地理解同步和異步的概念和區(qū)別!如果還有其他問題,請(qǐng)隨時(shí)提出。
16、vue2和vue3的區(qū)別
Vue.js 2和Vue.js 3之間有一些重要的區(qū)別,主要體現(xiàn)在以下幾個(gè)方面:
1、性能優(yōu)化:
Vue.js 3相較于Vue.js 2在性能上有一定提升。Vue.js 3采用了基于Proxy的響應(yīng)式系統(tǒng),相比Vue.js 2中的Object.defineProperty,性能更高效。
Vue.js 3還引入了一些新的優(yōu)化策略,如靜態(tài)樹提升(Static Tree Hoisting)和基于標(biāo)記的優(yōu)化(Template-based Optimization),進(jìn)一步提高了渲染性能。
2、組合式 API:
Vue.js 3引入了Composition API,這是一種新的API風(fēng)格,使得代碼邏輯可以更好地組織和復(fù)用。相比Vue.js 2的Options API,Composition API更加靈活和清晰,特別適合處理復(fù)雜組件邏輯。
3、Tree-shaking:
Vue.js 3通過改進(jìn)和優(yōu)化,支持更好的Tree-shaking,可以更有效地剔除未使用的代碼,減小項(xiàng)目的體積。
4、全局API調(diào)整:
在Vue.js 3中一些全局API發(fā)生了調(diào)整,需要通過app對(duì)象訪問,而不再是直接訪問Vue對(duì)象。
5、TypeScript支持:
Vue.js 3對(duì)TypeScript的支持更加完善,提供了更好的類型推斷和類型注解,使得開發(fā)更加可靠和便捷。
6、Teleport特性:
Vue.js 3引入了Teleport特性,可以將組件的內(nèi)容傳送到DOM樹的任何位置,有助于處理彈出框、對(duì)話框等場(chǎng)景。
7、Fragment支持:
Vue.js 3支持Fragment,可以在組件中直接返回多個(gè)根節(jié)點(diǎn),使得組件的編寫更加靈活。
8、錯(cuò)誤處理:
Vue.js 3提供了更好的錯(cuò)誤處理機(jī)制,幫助開發(fā)者更容易地調(diào)試和定位問題。
總的來說,Vue.js 3在性能、可維護(hù)性、開發(fā)體驗(yàn)等方面都有所改進(jìn),提供了更強(qiáng)大和靈活的功能來幫助開發(fā)者構(gòu)建現(xiàn)代化的Web應(yīng)用。如果你正在考慮選擇Vue.js 2還是Vue.js 3,可以根據(jù)項(xiàng)目需求和團(tuán)隊(duì)熟悉程度來進(jìn)行選擇。
17、vuex和pinia的區(qū)別
Vuex 和 Pinia 都是用于 Vue.js 應(yīng)用程序狀態(tài)管理的庫(kù),它們之間有一些區(qū)別和不同之處:
1、架構(gòu)差異:
Vuex 是 Vue.js 官方推薦的狀態(tài)管理庫(kù),包含了以下五個(gè)核心概念:
State(狀態(tài)):
State 即應(yīng)用程序中需要共享和管理的狀態(tài)數(shù)據(jù)。在 Vuex 中,整個(gè)應(yīng)用的狀態(tài)被存儲(chǔ)在一個(gè)單一的狀態(tài)樹(single state tree)中,即 Store。State 可以通過?this.$store.state?來訪問。
Getters(獲取器):
Getters 允許從 Store 中獲取狀態(tài),并對(duì)其進(jìn)行計(jì)算和派生得到新的狀態(tài)。它類似于 Vue 組件中的計(jì)算屬性,可以緩存一些狀態(tài),提高性能。可以通過?this.$store.getters?來訪問。
Mutations(突變):
Mutations 是用于修改 Store 中的狀態(tài)的唯一途徑。每個(gè) Mutation 都是一個(gè)純函數(shù),接受當(dāng)前狀態(tài)(state)作為第一個(gè)參數(shù),接受額外的參數(shù)作為第二個(gè)參數(shù)。Mutations 通過?commit?方法觸發(fā),例如:this.$store.commit('mutationName', payload)。
Actions(動(dòng)作):
Actions 類似于 Mutations,但是用于處理異步操作或批量操作。Actions 中可以包含任意異步操作,并且可以通過?commit?方法來觸發(fā) Mutations。Actions 通過?dispatch?方法觸發(fā),例如:this.$store.dispatch('actionName', payload)。
Modules(模塊):
Modules 允許將 Store 分割成多個(gè)獨(dú)立的模塊,每個(gè)模塊擁有自己的 State、Getters、Mutations 和 Actions。這樣可以更好地組織大型應(yīng)用的狀態(tài)管理邏輯,提高代碼可維護(hù)性。在創(chuàng)建 Store 實(shí)例時(shí),可以傳入一個(gè)包含 modules 屬性的對(duì)象,如?{ modules: { moduleA, moduleB } }。
Pinia 是一個(gè)由 Vue.js 社區(qū)開發(fā)的新一代狀態(tài)管理庫(kù),更加模塊化,采用了像 Vue 3 Composition API 一樣的組合式 API 風(fēng)格,使得狀態(tài)邏輯更容易組織和重用。
2、類型支持:
Vuex 在 Vue.js 2 中對(duì) TypeScript 的支持并不完善,需要額外的配置和類型定義文件。
Pinia 設(shè)計(jì)時(shí)考慮到了更好的 TypeScript 支持,并且在 Vue.js 3 中更為緊密地集成了類型支持。
3、響應(yīng)性:
Vuex 使用了基于對(duì)象的響應(yīng)式系統(tǒng)來跟蹤狀態(tài)的變化。
Pinia 利用了 Vue 3 的響應(yīng)式系統(tǒng),提供了更高效的狀態(tài)更新機(jī)制。
4、性能:
Pinia 在性能上可能會(huì)比 Vuex 更優(yōu)秀,特別是在大型應(yīng)用或者需要頻繁更新狀態(tài)的情況下,由于 Vue 3 的一些優(yōu)化特性和 Pinia 的設(shè)計(jì)理念,可能會(huì)表現(xiàn)更好。
5、API 設(shè)計(jì):
Vuex 遵循了一套固定的 API 設(shè)計(jì),如 mutations、actions 等,而且在 Vue.js 2 中需要借助輔助函數(shù)來使用。
Pinia 的 API 更加靈活,更加貼近 Composition API 的使用風(fēng)格,使得邏輯組織更清晰且更易于測(cè)試。
6、生態(tài)支持:
目前 Vuex 作為 Vue.js 官方推薦的狀態(tài)管理庫(kù),擁有更廣泛的生態(tài)支持和社區(qū)資源。
Pinia 雖然是一個(gè)新興的庫(kù),但也在不斷發(fā)展壯大,并且受到了越來越多開發(fā)者的關(guān)注和使用。
綜上所述,Vuex 和 Pinia 在架構(gòu)、類型支持、響應(yīng)性、性能、API 設(shè)計(jì)和生態(tài)支持等方面有所不同。選擇使用哪個(gè)庫(kù)取決于你的項(xiàng)目需求、團(tuán)隊(duì)技術(shù)棧和個(gè)人偏好。
18、vue通信方式
在 Vue 中,組件之間的通信是開發(fā)過程中經(jīng)常需要處理的一個(gè)重要問題。以下是一些常見的 Vue 組件通信方式:
1、Props / Events:父子組件之間通信最常見的方式是通過 props 向子組件傳遞數(shù)據(jù),以及通過 events 在子組件中觸發(fā)事件并將數(shù)據(jù)傳遞給父組件。
2、Vuex:用于在大型應(yīng)用程序中管理應(yīng)用程序級(jí)別的狀態(tài)。Vuex 提供了一個(gè)集中式的存儲(chǔ)倉(cāng)庫(kù),可以在任何組件中訪問和修改狀態(tài)。
3、$emit / $on:Vue 實(shí)例和非父子關(guān)系的組件之間可以使用 $emit 和 $on 來進(jìn)行事件通信。
4、Event Bus:創(chuàng)建一個(gè)全局的事件總線實(shí)例,可以用來在任何組件之間進(jìn)行通信。可以通過 $emit 和 $on 方法來發(fā)送和接收事件。
5、Provide / Inject:父組件通過 provide 提供數(shù)據(jù),然后子組件通過 inject 注入數(shù)據(jù)。這種方式可以實(shí)現(xiàn)祖先組件向后代組件的傳遞數(shù)據(jù)。
6、$attrs / $listeners:在組件中使用 $attrs 可以獲取父組件傳遞的所有屬性,并且使用 $listeners 可以獲取父組件綁定的所有事件監(jiān)聽器。
7、$parent / $children:通過 $parent 和 $children 可以直接訪問父組件和子組件的實(shí)例,從而進(jìn)行通信。
8、$refs:通過 ref 特性可以在父組件中引用子組件實(shí)例,從而直接調(diào)用子組件的方法或訪問數(shù)據(jù)。
9、Custom Events:除了使用內(nèi)置的事件機(jī)制外,還可以自定義事件來進(jìn)行組件間的通信。
19、vue2的響應(yīng)式Object.defineProperty和vue3的響應(yīng)式Proxy代理模式區(qū)別
Object.defineProperty和Proxy代理模式都是 JavaScript 中用于攔截對(duì)象操作并控制其行為的機(jī)制,但它們之間還是有一些區(qū)別的。
區(qū)別如下:
1、兼容性不同:
Object.defineProperty?是 ES5 標(biāo)準(zhǔn)中引入的,可以在大多數(shù)現(xiàn)代瀏覽器中使用,但還無(wú)法支持 IE8 及以下版本。
Proxy?是 ES6 標(biāo)準(zhǔn)中引入的,因此只能在較新的瀏覽器或 Node.js 等環(huán)境中使用。
2、攔截方式不同:
Object.defineProperty?可以對(duì)對(duì)象屬性進(jìn)行攔截,但是只能攔截屬性的讀取、修改等操作,而不能攔截對(duì)象本身的操作。
Proxy?對(duì)象可以攔截一個(gè)對(duì)象的所有操作,包括讀取、設(shè)置、刪除、遍歷等,還可以攔截 Object.create、Reflect API 等方法。
3、性能表現(xiàn)不同:
Object.defineProperty?的性能較好,但是只能監(jiān)聽到屬性的變化。如果需要監(jiān)聽對(duì)象的其他操作,需要手動(dòng)處理,會(huì)增加代碼復(fù)雜度。
Proxy?的性能略差一些,但可以監(jiān)聽到對(duì)象的所有操作,并且 API 更加完善和易用。
4、可取消性不同:
Object.defineProperty?無(wú)法取消對(duì)屬性的定義,一旦定義就無(wú)法更改(除非重新定義)。
Proxy?提供了?Proxy.revocable()?方法,可以生成一個(gè)可取消的代理對(duì)象,在不需要時(shí)可以通過調(diào)用?revoke()?方法來取消代理。
總體來說,Object.defineProperty和Proxy代理模式都是非常有用的機(jī)制,可以幫助開發(fā)者控制和管理對(duì)象的行為。在實(shí)際應(yīng)用中,可以根據(jù)實(shí)際情況選擇使用哪種機(jī)制。如果需要監(jiān)聽對(duì)象的所有操作,推薦使用Proxy;如果只需要監(jiān)聽屬性的變化,或者需要兼容老版本瀏覽器,可以使用Object.defineProperty。
20、vue2和vue3在處理數(shù)組有什么區(qū)別
Vue 2 和 Vue 3 在處理數(shù)組方面有一些區(qū)別,這些區(qū)別主要是由 Vue 3 引入的 Composition API 和 Reactivity API 所導(dǎo)致的。下面列出了一些在處理數(shù)組時(shí)的主要區(qū)別:
1、Vue 2:
在 Vue 2 中,由于 Vue 的響應(yīng)性系統(tǒng)是基于 Object.defineProperty 實(shí)現(xiàn)的,當(dāng)直接修改數(shù)組的某個(gè)元素時(shí)(例如:array[index] = value),Vue 無(wú)法檢測(cè)到這種變化,需要使用特定的方法來觸發(fā)響應(yīng)式更新,比如?Vue.set()?或者?array.splice()。
對(duì)數(shù)組的操作可以通過 Vue 提供的一些方法進(jìn)行,比如?push()、pop()、shift()、unshift()、splice()?等。
2、Vue 3:
在 Vue 3 中,引入了 Composition API 和 Reactivity API,使得響應(yīng)式系統(tǒng)更加靈活和強(qiáng)大。Vue 3 中使用 Proxy 來實(shí)現(xiàn)響應(yīng)式數(shù)據(jù),可以更好地監(jiān)聽數(shù)組的變化。
在 Vue 3 中,直接修改數(shù)組的某個(gè)元素時(shí),Vue 能夠檢測(cè)到這種變化并自動(dòng)觸發(fā)更新。
Vue 3 提供了?reactive、readonly、ref?等新的響應(yīng)式 API,可以更方便地處理數(shù)組的響應(yīng)式。
總的來說,在處理數(shù)組方面,Vue 3 相較于 Vue 2 更加智能和方便,能夠更好地響應(yīng)數(shù)組的變化并保持視圖與數(shù)據(jù)的同步。使用 Vue 3 的 Composition API 和 Reactivity API 可以更好地處理復(fù)雜的數(shù)據(jù)邏輯和數(shù)組操作。
21、重寫數(shù)組的七個(gè)方法
重寫數(shù)組的七個(gè)方法是指在 Vue 3 中使用 Composition API 和 Reactivity API 對(duì)數(shù)組的操作進(jìn)行重寫,以確保數(shù)組的響應(yīng)性。下面是對(duì)數(shù)組的七個(gè)常用方法進(jìn)行重寫的示例:
1、push:向數(shù)組末尾添加一個(gè)或多個(gè)元素,并返回新的長(zhǎng)度。
const myArray = ref([1, 2, 3]);const pushToMyArray = (value) => {
? myArray.value.push(value);
};
2、pop:刪除數(shù)組中的最后一個(gè)元素,并返回該元素的值。
const myArray = ref([1, 2, 3]);const popFromMyArray = () => {
? return myArray.value.pop();
};
3、shift:刪除數(shù)組中的第一個(gè)元素,并返回該元素的值。
const myArray = ref([1, 2, 3]);const shiftFromMyArray = () => {
? return myArray.value.shift();
};
4、unshift:向數(shù)組的開頭添加一個(gè)或多個(gè)元素,并返回新的長(zhǎng)度。
const myArray = ref([1, 2, 3]);const unshiftToMyArray = (value) => {
? myArray.value.unshift(value);
};
5、splice:刪除元素,并可選地插入新元素。
const myArray = ref([1, 2, 3, 4, 5]);const spliceMyArray = (start, deleteCount, ...items) => {
? myArray.value.splice(start, deleteCount, ...items);
};
6、slice:返回一個(gè)新數(shù)組,包含從開始到結(jié)束(不包括結(jié)束)選擇的數(shù)組的元素。
const myArray = ref([1, 2, 3, 4, 5]);
const slicedArray = computed(() => myArray.value.slice(1, 3));
7、map:創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中每個(gè)元素調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果。
const myArray = ref([1, 2, 3, 4, 5]);
const mappedArray = computed(() => myArray.value.map(item=> item * 2));
這些示例展示了如何使用 Vue 3 的 Composition API 和 Reactivity API 對(duì)數(shù)組的常用操作進(jìn)行重寫,以確保數(shù)組的響應(yīng)性和數(shù)據(jù)驅(qū)動(dòng)視圖更新。使用這種方式可以更好地控制數(shù)組的變化并保持?jǐn)?shù)據(jù)的一致性。
22、vuex和pinia的同步異步方面有區(qū)別嗎
在 Vuex 和 Pinia 中,同步和異步操作的處理方式有一些區(qū)別。以下是它們之間在同步和異步方面的一些區(qū)別:
Vuex:
1、同步操作:
在 Vuex 中,通常使用 mutation 來進(jìn)行同步狀態(tài)的更改。Mutation 必須是同步函數(shù),用于修改 Vuex 的 state。
當(dāng)需要進(jìn)行同步狀態(tài)的變更時(shí),可以通過提交 mutation 來修改 state。
2、異步操作:
對(duì)于異步操作,通常會(huì)使用 action。Action 可以包含任意異步操作,并且可以通過 context.commit 觸發(fā) mutation 來修改 state。
在 action 中可以進(jìn)行異步操作,如發(fā)起網(wǎng)絡(luò)請(qǐng)求、定時(shí)器等,待異步操作完成后再提交 mutation。
Pinia:
1、同步操作:
在 Pinia 中,依然使用類似 Vuex 的方式來處理同步操作,通過定義 mutations 來修改 state。
Mutations 在 Pinia 中也是同步的,用于直接修改 store 的 state。
2、異步操作:
Pinia 提供了更多的靈活性,可以直接在 actions 中返回 Promise 來處理異步操作。
在 Pinia 中,可以直接在 action 中執(zhí)行異步操作,并在異步操作完成后更新 state,無(wú)需顯式地通過 commit mutation。
總體來說,Vuex 和 Pinia 在同步操作上的處理方式比較相似,都是通過 mutations 來修改 state,但在異步操作方面,Pinia 提供了更加靈活的方式,允許在 actions 中直接處理異步邏輯并返回 Promise。這使得在處理異步操作時(shí)更加簡(jiǎn)潔和方便。希望這能夠幫助你理解 Vuex 和 Pinia 在同步和異步操作方面的區(qū)別。
23、 forin和forof循環(huán)區(qū)別
1、for...in 循環(huán)和 for...of 循環(huán)是 JavaScript 中的兩種不同的循環(huán)方式,它們有以下區(qū)別:
遍歷的對(duì)象類型不同:
for...in 循環(huán)遍歷的是一個(gè)對(duì)象的可枚舉屬性(包括原型鏈上的屬性)。
for...of 循環(huán)遍歷的是可迭代對(duì)象(如數(shù)組、字符串、Set、Map 等)的元素值。
2、遍歷的順序不同:
for...in 循環(huán)遍歷的順序是不確定的,可能會(huì)出現(xiàn)亂序的情況。
for...of 循環(huán)遍歷的順序是按照對(duì)象的迭代器返回的順序進(jìn)行的。
3、遍歷的方式不同:
for...in 循環(huán)使用的是對(duì)象的鍵來進(jìn)行遍歷,通過訪問對(duì)象的屬性名來獲取屬性值。
for...of 循環(huán)使用的是對(duì)象的值來進(jìn)行遍歷,直接訪問對(duì)象的元素值。
// for...in 循環(huán)示例const obj = { a: 1, b: 2, c: 3 };for (let key in obj) {
? console.log(key); // 輸出屬性名:a, b, c? console.log(obj[key]); // 輸出屬性值:1, 2, 3}// for...of 循環(huán)示例const arr = [1, 2, 3];for (let value of arr) {
? console.log(value); // 輸出元素值:1, 2, 3}
總結(jié)來說,for...in 循環(huán)適用于遍歷對(duì)象的屬性,而 for...of 循環(huán)適用于遍歷可迭代對(duì)象的元素值。根據(jù)具體的需求,選擇合適的循環(huán)方式來進(jìn)行遍歷操作。
24、 forin和forof都可以遍歷數(shù)組嗎
在 JavaScript 中,for...in 和 for...of 都可以用來遍歷數(shù)組,但它們有不同的行為和適用場(chǎng)景。
for...in:
適用范圍:for...in 主要用于遍歷對(duì)象的可枚舉屬性,但也可以用于遍歷數(shù)組。在遍歷數(shù)組時(shí),for...in 會(huì)枚舉數(shù)組的所有可枚舉屬性,包括原型鏈上的屬性。
注意事項(xiàng):由于 for...in 會(huì)枚舉原型鏈上的屬性,因此在遍歷數(shù)組時(shí)可能會(huì)導(dǎo)致意外的行為,例如遍歷到數(shù)組原型上的方法或?qū)傩浴R虼?,不推薦將 for...in 用于遍歷數(shù)組。
const arr = [1, 2, 3];for (let index in arr) {
? console.log(index); // 輸出 "0", "1", "2"}
for...of:
適用范圍:for...of 用于遍歷可迭代對(duì)象(包括數(shù)組、字符串、Map、Set、Generator 等)。在遍歷數(shù)組時(shí),for...of 只會(huì)遍歷數(shù)組的元素值,而不會(huì)涉及原型鏈上的屬性。
優(yōu)勢(shì):for...of 在遍歷數(shù)組時(shí)更加直觀和安全,不會(huì)導(dǎo)致意外的屬性遍歷,且語(yǔ)法更加簡(jiǎn)潔。
const arr = [1, 2, 3];for (let value of arr) {
? console.log(value); // 輸出 1, 2, 3}
總之,雖然 for...in 和 for...of 都可以用來遍歷數(shù)組,但由于 for...in 的一些潛在問題,推薦在遍歷數(shù)組時(shí)使用 for...of 來獲取更清晰和可靠的行為。
25、事件委托
事件委托(Event delegation)是一種常見的前端開發(fā)技術(shù),通過將事件處理程序綁定到父元素而不是每個(gè)子元素上,來提高性能和代碼簡(jiǎn)潔度的方法。
工作原理:
事件冒泡:在 HTML DOM 中,當(dāng)一個(gè)事件被觸發(fā)時(shí),會(huì)沿著 DOM 樹從目標(biāo)元素向上傳播,直到根節(jié)點(diǎn)。這個(gè)過程就是事件冒泡。
利用事件冒泡:事件委托利用事件冒泡的特性,在父元素上監(jiān)聽事件,然后通過判斷事件的目標(biāo)來執(zhí)行相應(yīng)的操作。這樣可以減少事件處理程序的數(shù)量,提高性能,并且適用于動(dòng)態(tài)添加的子元素。
優(yōu)點(diǎn):
性能優(yōu)化:減少了事件處理程序的數(shù)量,避免了給每個(gè)子元素都綁定事件處理程序。
代碼簡(jiǎn)潔:通過代理事件到父元素,可以使代碼更加簡(jiǎn)潔和易于維護(hù)。
適用動(dòng)態(tài)元素:對(duì)于動(dòng)態(tài)生成的子元素,事件委托可以自動(dòng)處理它們的事件。
示例代碼:

在上面的示例中,我們通過將點(diǎn)擊事件綁定到父元素<ul>上,然后通過判斷event.target的標(biāo)簽名來確定用戶點(diǎn)擊了哪個(gè)子元素<li>,從而執(zhí)行相應(yīng)的操作。
通過事件委托,我們只需要一個(gè)事件處理程序即可處理所有子元素的點(diǎn)擊事件,避免了為每個(gè)子元素都綁定事件處理程序的麻煩。
26、 怎么改變this的指向
在 JavaScript 中,可以使用以下幾種方式來改變函數(shù)內(nèi)部的this指向:
1、使用函數(shù)的?bind?方法:bind?方法會(huì)創(chuàng)建一個(gè)新的函數(shù),并將指定的?this?值綁定到函數(shù)內(nèi)部。這樣無(wú)論在何時(shí)調(diào)用該函數(shù),它的?this?都會(huì)保持不變。

2、使用箭頭函數(shù):箭頭函數(shù)不會(huì)創(chuàng)建自己的?this,而是繼承外部作用域的?this?值。因此,使用箭頭函數(shù)可以很方便地固定?this?的指向。

3、使用?call?或?apply?方法:call?和?apply?方法可以立即調(diào)用函數(shù),并傳遞一個(gè)指定的?this?值作為參數(shù)。

4、使用對(duì)象方法調(diào)用:將函數(shù)作為對(duì)象的方法調(diào)用時(shí),函數(shù)內(nèi)部的?this?將指向該對(duì)象。

需要注意的是,使用箭頭函數(shù)、bind、call 和 apply 方法可以顯式地改變 this 的指向,而使用對(duì)象方法調(diào)用時(shí) this 會(huì)隱式地指向該對(duì)象。
27、es6的箭頭函數(shù)可以改變this的指向嗎
實(shí)際上,ES6 中的箭頭函數(shù)并不能改變this的指向。與傳統(tǒng)的函數(shù)定義方式不同,箭頭函數(shù)沒有自己的this綁定,而是繼承了外部作用域的this值。
這意味著,在箭頭函數(shù)內(nèi)部,this的值是在定義函數(shù)時(shí)確定的,而不是在運(yùn)行時(shí)確定的。箭頭函數(shù)會(huì)自動(dòng)捕獲最近一層非箭頭函數(shù)作用域的this值作為自己的this值。
考慮以下例子:

在上面的例子中,person對(duì)象的sayHello方法中使用了箭頭函數(shù)。當(dāng)調(diào)用person.sayHello()時(shí),箭頭函數(shù)繼承了sayHello方法中的this值,即person對(duì)象本身。因此,箭頭函數(shù)內(nèi)部的this.name實(shí)際上是person.name,輸出結(jié)果為 "Hello, Alice"。
需要注意的是,箭頭函數(shù)適用于那些需要訪問外部作用域的this值的情況,但它并不適用于所有場(chǎng)景。在某些情況下,仍然需要使用傳統(tǒng)的函數(shù)定義方式來改變this的指向。
28、 bind、call、apply都分別傳什么參數(shù)
在 JavaScript 中,bind、call和apply這三個(gè)方法都可以用來顯式地改變函數(shù)的this指向。它們之間的主要區(qū)別在于參數(shù)的傳遞方式:
1.?bind?方法:
參數(shù):bind?方法接受一個(gè)參數(shù),即需要綁定給函數(shù)的?this?值。
作用:創(chuàng)建一個(gè)新函數(shù),該函數(shù)的?this?值會(huì)永久地綁定到指定的值上,不會(huì)立即執(zhí)行原函數(shù)。

2.?call?方法:
參數(shù):call?方法可以接受多個(gè)參數(shù),第一個(gè)參數(shù)是需要綁定給函數(shù)的?this?值,后續(xù)參數(shù)是傳遞給函數(shù)的參數(shù)列表。
作用:立即調(diào)用函數(shù),并將指定的?this?值和參數(shù)傳遞給函數(shù)。

3.?apply?方法:
參數(shù):apply?方法和?call?類似,但參數(shù)傳遞形式略有不同。第一個(gè)參數(shù)是需要綁定給函數(shù)的?this?值,第二個(gè)參數(shù)是一個(gè)數(shù)組,包含傳遞給函數(shù)的參數(shù)列表。
作用:立即調(diào)用函數(shù),并將指定的?this?值和參數(shù)數(shù)組傳遞給函數(shù)。

總結(jié)一下:
bind?方法用于創(chuàng)建一個(gè)新函數(shù),永久地綁定?this?值。
call?方法用于立即調(diào)用函數(shù),并傳遞參數(shù)列表。
apply?方法同樣用于立即調(diào)用函數(shù),但參數(shù)以數(shù)組形式傳遞。
29、深拷貝和淺拷貝
深拷貝和淺拷貝是在編程中經(jīng)常遇到的概念,它們涉及復(fù)制對(duì)象或數(shù)據(jù)結(jié)構(gòu)時(shí)所采取的不同策略。讓我們來看看它們各自的含義和區(qū)別:
1、淺拷貝:
含義:淺拷貝創(chuàng)建了一個(gè)新的對(duì)象或數(shù)組,但只復(fù)制了原始對(duì)象或數(shù)組的引用,而不是其中的內(nèi)容。
特點(diǎn):新對(duì)象和原對(duì)象會(huì)共享相同的內(nèi)部對(duì)象,當(dāng)修改其中一個(gè)對(duì)象內(nèi)部的內(nèi)容時(shí),另一個(gè)對(duì)象也會(huì)受到影響。
示例代碼:

2、深拷貝:
含義:深拷貝創(chuàng)建了一個(gè)新的對(duì)象或數(shù)組,并遞歸地復(fù)制原始對(duì)象或數(shù)組中的所有內(nèi)部對(duì)象,而不僅僅是引用。
特點(diǎn):新對(duì)象和原對(duì)象完全獨(dú)立,對(duì)一個(gè)對(duì)象的修改不會(huì)影響另一個(gè)對(duì)象。
示例代碼:

需要注意的是,深拷貝可能會(huì)更消耗內(nèi)存和性能,尤其是當(dāng)處理大型、嵌套復(fù)雜的對(duì)象或數(shù)組時(shí)。在選擇拷貝策略時(shí),需要根據(jù)具體情況權(quán)衡使用淺拷貝還是深拷貝。
30、 數(shù)據(jù)如何實(shí)現(xiàn)深拷貝
1、實(shí)現(xiàn)深拷貝是為了創(chuàng)建一個(gè)新的對(duì)象,該對(duì)象與原始對(duì)象具有相同的值,但是在內(nèi)存中是獨(dú)立的。下面介紹幾種常見的實(shí)現(xiàn)深拷貝的方法:
遞歸拷貝:遍歷原始對(duì)象的所有屬性,如果屬性是對(duì)象或數(shù)組,則遞歸調(diào)用深拷貝函數(shù)進(jìn)行拷貝。

2、JSON 序列化與反序列化:使用 JSON.stringify 將原始對(duì)象轉(zhuǎn)換為字符串,再使用 JSON.parse 將字符串轉(zhuǎn)換為新的對(duì)象。這種方法可以實(shí)現(xiàn)較簡(jiǎn)單的深拷貝,但無(wú)法拷貝函數(shù)和特殊對(duì)象(如正則表達(dá)式)。

3、使用第三方庫(kù):可以使用一些第三方庫(kù),如 lodash 的 cloneDeep 方法或者 jQuery 的 extend 方法來實(shí)現(xiàn)深拷貝。

需要注意的是,某些對(duì)象屬性可能引用了其他對(duì)象,而深拷貝會(huì)遞歸復(fù)制所有的對(duì)象,這可能導(dǎo)致循環(huán)引用或棧溢出的問題。因此,在進(jìn)行深拷貝時(shí),應(yīng)該考慮處理循環(huán)引用的情況,或者使用適當(dāng)?shù)姆椒▉硐拗粕疃瓤截惖膶蛹?jí)。另外,拷貝過程中可能會(huì)丟失對(duì)象原型鏈上的方法和屬性,需要根據(jù)實(shí)際需求進(jìn)行處理。
31、 一個(gè)對(duì)象里面有兩個(gè)屬性一個(gè)方法怎么實(shí)現(xiàn)深拷貝
要實(shí)現(xiàn)對(duì)一個(gè)對(duì)象里面有兩個(gè)屬性和一個(gè)方法的深拷貝,你可以使用遞歸的方式來復(fù)制對(duì)象及其內(nèi)部的屬性。下面是一個(gè)簡(jiǎn)單的示例代碼,演示如何實(shí)現(xiàn)深度拷貝一個(gè)包含屬性和方法的對(duì)象:

在上面的示例中,deepCopy函數(shù)通過遞歸的方式遍歷對(duì)象的屬性,并對(duì)每個(gè)屬性進(jìn)行深拷貝操作,確保生成了一個(gè)完全獨(dú)立的新對(duì)象,包括其中的方法。這樣就實(shí)現(xiàn)了深度拷貝一個(gè)包含屬性和方法的對(duì)象。
請(qǐng)注意,對(duì)于包含函數(shù)等特殊屬性的深拷貝需要謹(jǐn)慎處理,因?yàn)楹瘮?shù)可能無(wú)法直接被序列化和復(fù)制。
32、箭頭函數(shù)有哪些特點(diǎn)
箭頭函數(shù)是 ES6 中引入的一種新的函數(shù)定義方式,具有如下特點(diǎn):
簡(jiǎn)潔性:箭頭函數(shù)可以更加簡(jiǎn)潔地定義函數(shù),省略了 function 關(guān)鍵字和 return 關(guān)鍵字(在某些情況下可以省略 {} 和 return),使代碼更加精煉。
綁定 this:箭頭函數(shù)沒有自己的 this,它會(huì)捕獲所在上下文的 this 值。這意味著在箭頭函數(shù)內(nèi)部使用 this 時(shí),它指向的是箭頭函數(shù)被創(chuàng)建時(shí)的環(huán)境中的 this,而不是調(diào)用時(shí)的環(huán)境。
不能作為構(gòu)造函數(shù):箭頭函數(shù)不能被用作構(gòu)造函數(shù),因此不能通過 new 關(guān)鍵字來實(shí)例化對(duì)象。
不能使用 arguments 對(duì)象:箭頭函數(shù)沒有自己的 arguments 對(duì)象,但可以訪問外部函數(shù)的 arguments 對(duì)象。
沒有原型:箭頭函數(shù)沒有原型,因此無(wú)法通過 new 關(guān)鍵字來創(chuàng)建實(shí)例。
不能改變 this 的指向:由于箭頭函數(shù)中的 this 是詞法作用域,因此無(wú)法通過 call()、apply()、bind() 方法來改變 this 的指向。
不能使用 yield 關(guān)鍵字:箭頭函數(shù)不能用作 Generator 函數(shù),因此不能使用 yield 關(guān)鍵字來暫停和恢復(fù)執(zhí)行。
總的來說,箭頭函數(shù)適合用于簡(jiǎn)單的函數(shù)表達(dá)式,特別是在需要保持 this 指向外層作用域的情況下。但是在需要使用到 this、arguments、原型等情況下,需要謹(jǐn)慎選擇是否使用箭頭函數(shù)來定義函數(shù)。
33、箭頭函數(shù)沒有自己的 arguments 對(duì)象,可以使用 rest 參數(shù) ...args 來代替,讀取到的是什么
當(dāng)使用 rest 參數(shù)...args來代替箭頭函數(shù)中缺失的arguments對(duì)象時(shí),...args會(huì)將箭頭函數(shù)接收到的所有參數(shù)組成一個(gè)數(shù)組。這意味著在箭頭函數(shù)內(nèi)部,你可以通過...args來訪問所有傳入的參數(shù),而不需要使用arguments對(duì)象。
例如,假設(shè)有一個(gè)箭頭函數(shù)如下所示:
constsum= (...args) => {console.log(args);};
在這個(gè)箭頭函數(shù)中,...args將接收到的所有參數(shù)組成一個(gè)數(shù)組,并打印輸出該數(shù)組。比如調(diào)用sum(1, 2, 3)時(shí),箭頭函數(shù)內(nèi)部會(huì)打印出[1, 2, 3]。
使用 rest 參數(shù)...args可以更加方便地處理箭頭函數(shù)接收到的參數(shù),而不需要使用arguments對(duì)象進(jìn)行操作。同時(shí),...args提供了更清晰、直觀的方式來處理函數(shù)的參數(shù)列表。
...是關(guān)鍵字...后面的args是可以變成別的比如aa,bb,cc
34、如何自己實(shí)現(xiàn)一個(gè)v-model指令
要自己實(shí)現(xiàn)一個(gè) V-Model 指令,你可以按照以下步驟進(jìn)行:
1、創(chuàng)建一個(gè)自定義指令:使用你選擇的編程語(yǔ)言和框架,創(chuàng)建一個(gè)新的自定義指令。在指令中,你需要定義指令的名稱、綁定方式和相關(guān)邏輯。
2、獲取綁定的值:在指令的邏輯中,獲取綁定到 v-model 的值。這可以通過讀取傳入指令的參數(shù)或通過指令的上下文訪問父組件的屬性來實(shí)現(xiàn)。
3、監(jiān)聽輸入事件:在指令中添加對(duì)用戶輸入事件的監(jiān)聽。這可以是輸入框的input事件、復(fù)選框的change事件或其他合適的事件,具體取決于你希望指令用于哪種類型的輸入元素。
4、更新綁定的值:當(dāng)用戶輸入事件觸發(fā)時(shí),在指令的邏輯中更新綁定到 v-model 的值。這可以通過修改指令參數(shù)或通過指令上下文向父組件發(fā)送事件來實(shí)現(xiàn)。
5、反向同步:在指令邏輯中處理從父組件傳遞下來的更新。這包括在初始渲染時(shí)將父組件的值同步到輸入元素中,并在父組件的值變化時(shí)更新輸入元素。
6、使用指令:在你的應(yīng)用程序中使用自定義的 v-model 指令。將它綁定到你希望雙向綁定的輸入元素上,然后使用它來更新和獲取數(shù)據(jù)。
需要注意的是,具體的實(shí)現(xiàn)步驟可能因使用的編程語(yǔ)言和框架而有所不同。你需要查閱相關(guān)文檔和教程,以了解如何在你選擇的環(huán)境中創(chuàng)建自定義指令并進(jìn)行相應(yīng)的操作。
35、封裝一個(gè)v-model對(duì)話框組件,使用什么方法,怎么封裝
1. 創(chuàng)建對(duì)話框組件
首先,創(chuàng)建一個(gè)對(duì)話框組件,該組件應(yīng)該包含一個(gè)內(nèi)部的值(比如visible表示對(duì)話框是否可見)以及觸發(fā)對(duì)話框關(guān)閉的方法。

2. 使用?v-model?綁定
在父組件中,可以使用這個(gè)自定義的對(duì)話框組件,并通過v-model將對(duì)話框的顯示狀態(tài)與父組件的數(shù)據(jù)進(jìn)行雙向綁定。

在這個(gè)例子中,我們使用v-model將dialogVisible與CustomDialog的value屬性進(jìn)行雙向綁定,從而實(shí)現(xiàn)了一個(gè)帶有v-model功能的對(duì)話框組件。
通過上述步驟,你就可以封裝一個(gè)帶有v-model功能的對(duì)話框組件,并在父組件中使用它了。
36、v-model是誰(shuí)的語(yǔ)法糖
v-model是 Vue.js 框架提供的一個(gè)指令,用于實(shí)現(xiàn)表單元素和組件之間的雙向數(shù)據(jù)綁定。在 Vue.js 中,v-model實(shí)際上是一種語(yǔ)法糖(syntactic sugar),它簡(jiǎn)化了組件或表單元素與數(shù)據(jù)之間的交互。
具體來說,v-model實(shí)際上展開為兩個(gè)操作:
綁定一個(gè)值到表單元素或組件的屬性上;
在該表單元素或組件上監(jiān)聽對(duì)應(yīng)事件并更新綁定的值。
例如,在一個(gè)輸入框上使用v-model可以實(shí)現(xiàn)雙向綁定,即輸入框中的內(nèi)容更新會(huì)自動(dòng)反映到綁定的變量上,同時(shí)修改綁定的變量也會(huì)自動(dòng)更新到輸入框中。
因此,v-model的出現(xiàn)使得數(shù)據(jù)綁定更加簡(jiǎn)潔和便捷,避免了手動(dòng)處理數(shù)據(jù)變化和事件監(jiān)聽的繁瑣步驟。這也是 Vue.js 所強(qiáng)調(diào)的響應(yīng)式和聲明式編程的特點(diǎn)之一。
總之,v-model是 Vue.js 提供的方便的語(yǔ)法糖,用于簡(jiǎn)化數(shù)據(jù)綁定和事件處理的操作。
37、不簡(jiǎn)化在組件內(nèi)部怎么實(shí)現(xiàn)v-model
在 Vue.js 組件內(nèi)部,如果需要實(shí)現(xiàn)類似v-model的雙向綁定功能,你可以手動(dòng)編寫代碼來處理數(shù)據(jù)的傳遞和更新。以下是一個(gè)示例,展示如何在組件內(nèi)部實(shí)現(xiàn)類似v-model的功能:
假設(shè)我們有一個(gè)自定義的輸入框組件CustomInput,我們希望在組件內(nèi)部實(shí)現(xiàn)雙向綁定。

在這個(gè)示例中,CustomInput組件內(nèi)部維護(hù)了一個(gè)internalValue,用來保存輸入框的值。通過監(jiān)聽輸入框的input事件,組件可以實(shí)時(shí)更新internalValue的值,并通過$emit方法將新值傳遞給父組件。
在父組件中,可以使用該自定義輸入框組件,并通過v-bind和v-on手動(dòng)實(shí)現(xiàn)雙向綁定:

通過以上方式,你可以在 Vue.js 組件內(nèi)部手動(dòng)實(shí)現(xiàn)類似 v-model 的雙向綁定功能。這種方式雖然需要更多的代碼,但也能靈活地控制數(shù)據(jù)的傳遞和更新過程。
38、 vue2中的選項(xiàng)api中v-model的key是什么
在 Vue 2.x 中,如果你想在自定義組件中使用v-model,需要使用一個(gè)名為model的選項(xiàng)來定義v-model的行為。具體來說,你可以在組件選項(xiàng)中使用model選項(xiàng)來指定v-model的屬性名和事件名。
下面是一個(gè)簡(jiǎn)單的示例,展示了如何在 Vue 2.x 中定義一個(gè)帶有v-model的自定義組件:

在上面的示例中,我們使用了model選項(xiàng)來定義v-model的屬性名為value,事件名為input。這樣一來,在父組件中使用<custom-input v-model="message"></custom-input>就可以實(shí)現(xiàn)雙向綁定。
總結(jié)一下,在 Vue 2.x 中,可以通過在自定義組件中使用model選項(xiàng)來指定v-model的屬性名和事件名,從而實(shí)現(xiàn)雙向數(shù)據(jù)綁定功能。
39、 vue3的modelValue怎么說
在 Vue 3 中,使用v-model指令進(jìn)行雙向數(shù)據(jù)綁定時(shí),父組件傳遞給子組件的值會(huì)被命名為modelValue。這是因?yàn)樵?Vue 3 中,為了更清晰地表示該值是用于雙向綁定的,將其命名為modelValue。同時(shí),子組件需要通過emit('update:modelValue', newValue)來更新modelValue的值。
以下是一個(gè)簡(jiǎn)單的示例,展示了在 Vue 3 中如何使用v-model和modelValue:

然后,在自定義輸入框組件 CustomInput 中,你可以使用 modelValue 來接收父組件傳遞的值,并通過 emits 選項(xiàng)來觸發(fā)更新:

在這個(gè)示例中,父組件中使用了v-model="message",因此message將作為modelValue傳遞給了CustomInput組件。
總之,在 Vue 3 中,使用v-model進(jìn)行雙向數(shù)據(jù)綁定時(shí),父組件傳遞給子組件的值會(huì)被命名為modelValue。
40、nextTick是干什么的
在 Vue.js 中,nextTick是一個(gè)異步方法,用于在 DOM 更新之后執(zhí)行特定的操作。當(dāng)你對(duì)數(shù)據(jù)進(jìn)行修改時(shí),Vue 并不會(huì)立即更新 DOM,而是將 DOM 更新操作放入隊(duì)列中,在下一個(gè)事件循環(huán)周期中執(zhí)行更新。而nextTick方法可以讓你在當(dāng)前 DOM 更新周期結(jié)束后,下一個(gè) DOM 更新周期開始前執(zhí)行回調(diào)函數(shù)。
使用this.$nextTick()可以確保在 Vue 更新 DOM 后立即執(zhí)行回調(diào)函數(shù),這樣你就可以在 DOM 更新完成后進(jìn)行操作,比如獲取更新后的 DOM 元素或執(zhí)行其他任務(wù)。
下面是一個(gè)簡(jiǎn)單的示例,演示了如何使用nextTick方法:

在上面的示例中,我們?cè)诮M件掛載后修改了message數(shù)據(jù),并使用this.$nextTick()來確保在 DOM 更新后獲取更新后的 DOM 元素。這樣可以保證我們能夠在獲取 DOM 元素時(shí)拿到最新的內(nèi)容。
總而言之,nextTick方法允許你在當(dāng)前 DOM 更新周期結(jié)束后執(zhí)行回調(diào)函數(shù),確保能夠操作最新的 DOM 元素。
41、 vue的自定義指令生命周期
在 Vue 中,自定義指令可以通過鉤子函數(shù)來定義和控制其行為。自定義指令的生命周期鉤子函數(shù)包括:
bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。
inserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(僅保證父節(jié)點(diǎn)存在,但不一定已被插入文檔中)。如果指令作用于普通元素,則表示元素已經(jīng)插入文檔中。如果指令作用于組件,則表示組件已經(jīng)掛載。
update:當(dāng)被綁定的元素所在的組件更新時(shí)調(diào)用,而不論元素本身是否發(fā)生變化。但是,通過傳入的參數(shù)及更新的參數(shù)之間的差異信息,你可以根據(jù)需求進(jìn)行相應(yīng)的 DOM 操作。
componentUpdated:在被綁定元素所在的組件完成一次更新周期時(shí)調(diào)用。
unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。
下面是一個(gè)簡(jiǎn)單的示例,展示了如何定義一個(gè)自定義指令,并使用其中的生命周期鉤子函數(shù):

在上面的示例中,我們定義了一個(gè)名為focus的自定義指令,并實(shí)現(xiàn)了inserted和update鉤子函數(shù)來控制元素的焦點(diǎn)狀態(tài)。
通過這些生命周期鉤子函數(shù),你可以在不同階段干預(yù)自定義指令的行為,從而實(shí)現(xiàn)對(duì)元素的定制化操作。希望這能夠幫助你理解 Vue 自定義指令的生命周期!
42、 ts中接口如何實(shí)現(xiàn)繼承
在 TypeScript 中,接口可以通過繼承來擴(kuò)展其他接口。接口的繼承和類的繼承有些相似,通過extends關(guān)鍵字可以實(shí)現(xiàn)接口之間的繼承關(guān)系。
下面是一個(gè)簡(jiǎn)單的示例,演示了如何在 TypeScript 中實(shí)現(xiàn)接口的繼承:

在上面的示例中,我們定義了一個(gè)基礎(chǔ)接口Shape,它包含一個(gè)color屬性。然后定義了一個(gè)接口Square,它繼承自Shape接口并新增了一個(gè)sideLength屬性。最后創(chuàng)建了一個(gè)Square類型的對(duì)象square,并分別輸出了color和sideLength屬性的值。
通過接口的繼承,我們可以構(gòu)建出更加復(fù)雜和具有層次結(jié)構(gòu)的接口,從而提高代碼的可維護(hù)性和可擴(kuò)展性。
43、 interface可以繼承一個(gè)類嗎
在 TypeScript 中,接口是用來描述對(duì)象的形狀的,而類是用來創(chuàng)建對(duì)象的模板并包含屬性和方法的實(shí)現(xiàn)。因此,接口無(wú)法直接繼承一個(gè)類,因?yàn)轭惏司唧w的實(shí)現(xiàn)細(xì)節(jié),而接口只描述對(duì)象應(yīng)該具有的結(jié)構(gòu)。
雖然接口不能直接繼承類,但可以通過將類抽象成接口的方式來間接實(shí)現(xiàn)類似的效果。你可以創(chuàng)建一個(gè)接口來描述類的結(jié)構(gòu),并在其他接口中繼承這個(gè)描述類結(jié)構(gòu)的接口。
下面是一個(gè)示例,展示了如何將類抽象成接口,并在另一個(gè)接口中繼承這個(gè)抽象接口:

在上面的示例中,我們首先定義了一個(gè)類Person,然后將其抽象成接口PersonInterface。接著定義了一個(gè)繼承自PersonInterface的接口Employee,并添加了一個(gè)id屬性。最后創(chuàng)建了一個(gè)Employee類型的對(duì)象employee并輸出其屬性值。
通過將類抽象成接口,我們可以在接口之間建立關(guān)系,實(shí)現(xiàn)類似繼承的效果。希望這個(gè)解釋能夠幫助你理解在 TypeScript 中如何處理接口和類之間的關(guān)系。
44、 ts中const和readonly的區(qū)別
在 TypeScript 中,const和readonly都用于表示變量或?qū)傩缘牟豢尚薷男?,但它們有一些區(qū)別。
1、const:const?是用于聲明常量的關(guān)鍵字。當(dāng)你使用?const?聲明一個(gè)變量時(shí),它將具有不可修改的值。這意味著一旦你給一個(gè)變量賦值,就無(wú)法再修改它。const?只能在變量聲明時(shí)使用,不能用于類的成員。例如:

2、readonly:readonly?是用于聲明只讀屬性或參數(shù)的關(guān)鍵字。使用?readonly?修飾的屬性或參數(shù)不能在其聲明后被修改。readonly?可以用于變量、類的成員和接口的屬性。例如:

在上面的示例中,radius屬性使用readonly關(guān)鍵字進(jìn)行聲明,因此在構(gòu)造函數(shù)之外無(wú)法修改它的值。
總結(jié):
const?用于聲明常量,只能在變量聲明時(shí)使用,并且無(wú)法修改常量的值。
readonly?用于聲明只讀屬性或參數(shù),可以修飾變量、類的成員和接口的屬性,聲明后無(wú)法修改其值。
希望這個(gè)解釋能夠幫助你理解 TypeScript 中const和readonly的區(qū)別。
45、隊(duì)和棧的區(qū)別
隊(duì)列(Queue)和棧(Stack)是兩種常見的數(shù)據(jù)結(jié)構(gòu),它們?cè)跀?shù)據(jù)的存儲(chǔ)和訪問方式上有著明顯的區(qū)別:
1、隊(duì)列:
隊(duì)列是一種先進(jìn)先出(First In, First Out,F(xiàn)IFO)的數(shù)據(jù)結(jié)構(gòu),類似于現(xiàn)實(shí)生活中的排隊(duì)。
元素只能從隊(duì)列的一端(稱為隊(duì)尾)添加,而只能從另一端(稱為隊(duì)首)移除。
隊(duì)列常用于實(shí)現(xiàn)廣度優(yōu)先搜索(BFS)、任務(wù)調(diào)度等場(chǎng)景,如打印隊(duì)列、消息隊(duì)列等。
2、棧:
棧是一種后進(jìn)先出(Last In, First Out,LIFO)的數(shù)據(jù)結(jié)構(gòu),類似于現(xiàn)實(shí)生活中的堆疊盤子。
元素只能從棧頂添加和移除,即最后進(jìn)入棧的元素將會(huì)最先被移除。
棧常用于實(shí)現(xiàn)函數(shù)調(diào)用、表達(dá)式求值、撤銷操作等場(chǎng)景,如瀏覽器的頁(yè)面歷史記錄。
總的來說,隊(duì)列和棧在數(shù)據(jù)的存取規(guī)則上有所不同,因此在不同的場(chǎng)景下選擇合適的數(shù)據(jù)結(jié)構(gòu)可以更好地滿足問題的需求
46、 ts中類的方法重載
在 TypeScript 中,類的方法重載可以通過函數(shù)重載來實(shí)現(xiàn)。函數(shù)重載是指在同一個(gè)作用域內(nèi),根據(jù)參數(shù)的不同而執(zhí)行不同的操作。下面是一個(gè)簡(jiǎn)單的示例,演示了如何在 TypeScript 中對(duì)類的方法進(jìn)行重載:

在上面的示例中,Calculator類中的add方法被重載了兩次:一次接受兩個(gè)參數(shù)為數(shù)字,返回值也為數(shù)字;另一次接受兩個(gè)參數(shù)為字符串,返回值也為字符串。在類的實(shí)例化后,根據(jù)傳入?yún)?shù)的類型,TypeScript 編譯器會(huì)自動(dòng)調(diào)用對(duì)應(yīng)的重載方法。
需要注意的是,在 TypeScript 中,函數(shù)重載要求先定義一系列的函數(shù)聲明(只有參數(shù)列表和返回值類型),然后再定義對(duì)應(yīng)的函數(shù)實(shí)現(xiàn)。這樣就能實(shí)現(xiàn)對(duì)同一個(gè)方法根據(jù)參數(shù)類型的不同進(jìn)行重載。