經(jīng)典前端面試題_第1頁
經(jīng)典前端面試題_第2頁
經(jīng)典前端面試題_第3頁
經(jīng)典前端面試題_第4頁
經(jīng)典前端面試題_第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

2/22023年經(jīng)典前端面試題一、HTML/CSS篇1、HTML5應(yīng)用緩存和常規(guī)的HTML瀏覽器緩存有什么差別?【僅供參考】

HTML5應(yīng)用緩存最關(guān)鍵的就是支持離線應(yīng)用,可獲取少數(shù)或者全部網(wǎng)站內(nèi)容,包括HTML、CSS、圖像和JavaScript腳本并存在本地。該特性提升了網(wǎng)站的性能,可通過如下方式實現(xiàn)。

<!doctypehtml>

<htmlmanifest="example.appcache">

</html>

與傳統(tǒng)的瀏覽器緩存比較,該特性并不強(qiáng)制要求用戶訪問網(wǎng)站。2、HTML5為什么只需要寫<!doctypehtm>?【僅供參考】

HTML5不基于SGML,因此不需要對DTD進(jìn)行引用,但是需要DOCTYPE來規(guī)范瀏覽器的行為(讓瀏覽器按照它們的方式來運(yùn)行)。而HTM4.01基于SGML,所以需要對DTD進(jìn)行引用,才能告知瀏覽器文檔所使用的類型。3、HTML5的離線儲存怎么使用,工作原理能不能解釋一下?【僅供參考】

在用戶沒有與因特網(wǎng)連接時,可以正常訪問站點(diǎn)或應(yīng)用,在用戶與因特網(wǎng)連接時,更新用戶機(jī)器上的緩存文件。

原理:HTML5的離線存儲是基于一個新建的.appcache文件的緩存機(jī)制(不是存儲技術(shù)),通過這個文件上的解析清單離線存儲資源,這些資源就會像cookie一樣被存儲了下來。之后當(dāng)網(wǎng)絡(luò)在處于離線狀態(tài)下時,瀏覽器會通過被離線存儲的數(shù)據(jù)進(jìn)行頁面展示。

如何使用:

創(chuàng)建一個和html同名的manifest文件,然后在頁面頭部像下面一樣加入一個manifest的屬性。

<htmllang="en"manifest="index.manifest">

在如下cache.manifest文件的編寫離線存儲的資源。

CACHEMANIFEST

#v0.11

CACHE:

js/app.js

css/style.css

NETWORK:

resourse/logo.png

FALLBACK:

//offline.html

CACHE:表示需要離線存儲的資源列表,由于包含manifest文件的頁面將被自動離線存儲,所以不需要把頁面自身也列出來。

NETWORK:表示在它下面列出來的資源只有在在線的情況下才能訪問,他們不會被離線存儲,所以在離線情況下無法使用這些資源。不過,如果在CACHE和NETWORK中有一個相同的資源,那么這個資源還是會被離線存儲,也就是說CACHE的優(yōu)先級更高。

FALLBACK:表示如果訪問第一個資源失敗,那么就使用第二個資源來替換他,比如上面這個文件表示的就是如果訪問根目錄下任何一個資源失敗了,那么就去訪問offline.html。

(3)在離線狀態(tài)時,操作window.applicationCache進(jìn)行離線緩存的操作。

如何更新緩存:

1、更新manifest文件

2、通過javascript操作

3、清除瀏覽器緩存

注意事項:

1、瀏覽器對緩存數(shù)據(jù)的容量限制可能不太一樣(某些瀏覽器設(shè)置的限制是每個站點(diǎn)5MB)。

2、如果manifest文件,或者內(nèi)部列舉的某一個文件不能正常下載,整個更新過程都將失敗,瀏覽器繼續(xù)全部使用老的緩存。

3、引用manifest的html必須與manifest文件同源,在同一個域下。

4、FALLBACK中的資源必須和manifest文件同源。

5、當(dāng)一個資源被緩存后,該瀏覽器直接請求這個絕對路徑也會訪問緩存中的資源。

6、站點(diǎn)中的其他頁面即使沒有設(shè)置manifest屬性,請求的資源如果在緩存中也從緩存中訪問。

7、當(dāng)manifest文件發(fā)生改變時,資源請求本身也會觸發(fā)更新。4、本地存儲和會話(事務(wù))存儲之間的區(qū)別是什么?【僅供參考】

本地存儲數(shù)據(jù)持續(xù)永久,但是會話存儲在瀏覽器打開時有效,在瀏覽器關(guān)閉時會話重置存儲數(shù)據(jù)。5、HTML5應(yīng)用程序緩存為應(yīng)用帶來什么優(yōu)勢?【僅供參考】

應(yīng)用程序緩存為應(yīng)用帶來3個優(yōu)勢。

(1)離線瀏覽,讓用戶可在應(yīng)用離線時(網(wǎng)絡(luò)不可用時)使用它們。

(2)速度,讓已緩存資源加載得更快。

(3)減少服務(wù)器負(fù)載,讓瀏覽器將只下載服務(wù)器更新過的資源。6、如何區(qū)別HTML和HTML5?【僅供參考】

用DOCTYPE聲明新增的結(jié)構(gòu)元素和功能元素來區(qū)別它們。7、如何進(jìn)行網(wǎng)站性能優(yōu)化【僅供參考】

content方面

1、減少HTTP請求:合并文件、CSS精靈、inlineImage

2、減少DNS查詢:DNS緩存、將資源分布到恰當(dāng)數(shù)量的主機(jī)名

3、減少DOM元素數(shù)量

Server方面

1、使用CDN

2、配置ETag

3、對組件使用Gzip壓縮

Cookie方面

1、減小cookie大小

css方面

1、將樣式表放到頁面頂部

2、不使用CSS表達(dá)式

3、使用<link>不使用@import

Javascript方面

1、將腳本放到頁面底部

2、將javascript和css從外部引入

3、壓縮javascript和css

4、刪除不需要的腳本

5、減少DOM訪問

圖片方面

1、優(yōu)化圖片:根據(jù)實際顏色需要選擇色深、壓縮

2、優(yōu)化css精靈

3、不要在HTML中拉伸圖片8、HTML5Canvas元素有什么作用?【僅供參考】

Canvas元素用于在網(wǎng)頁上繪制圖形,該元素標(biāo)簽的強(qiáng)大之處在于可以直接在HTML上進(jìn)行圖形操作。9、什么是HTML5?【僅供參考】

HTML5是最新的HTML標(biāo)準(zhǔn),它的主要目標(biāo)是提供所有內(nèi)容,而不需要任何Flash、SilverLight等的額外插件,這些內(nèi)容來自動畫、視頻、富GUI等

HTML5是萬維網(wǎng)聯(lián)盟(W3C)和網(wǎng)絡(luò)超文本應(yīng)用技術(shù)工作組(WHATWG)合作輸出的。10、iframe的優(yōu)缺點(diǎn)?【僅供參考】

優(yōu)點(diǎn):

解決加載緩慢的第三方內(nèi)容如圖標(biāo)和廣告等的加載問題

Securitysandbox

并行加載腳本

缺點(diǎn):

iframe會阻塞主頁面的Onload事件

即時內(nèi)容為空,加載也需要時間

沒有語意11、為什么HTML5里面不需要DTD(DocumentTypeDefinition,文檔類型定義)?如果不放入<!doctypehtml>標(biāo)簽,HTML5還會工作嗎?【僅供參考】

HTML5沒有使用SGML或者XHTML,它是一個全新的類型,因此不需要參考DTD。對于HTML5,僅須放置下面的文檔類型代碼,讓瀏覽器識別HTML5文檔。

如果不放入<!doctypehtml>標(biāo)簽,HTML5不會工作。瀏覽器將不能識別出它是HTML文檔,同時HTML5的標(biāo)簽將不能正常工作。12、如果把HTML5看成一個開放平臺,它的構(gòu)建模塊有哪些?【僅供參考】

如果把HTML5看成一個開放平臺,它的構(gòu)建模塊至少包括以下幾個,如<nav><header><section><footer>。

≤nav>標(biāo)簽用來將具有導(dǎo)航性質(zhì)的鏈接劃分在一起,使代碼結(jié)構(gòu)在語義化方面更加準(zhǔn)確

<header>標(biāo)簽用來定義文檔的頁眉。

<section>標(biāo)簽用來描述文檔的結(jié)構(gòu)。

<footer>標(biāo)簽用來定義頁腳。在典型情況下,該元素會包含文檔作者的姓名、文檔的創(chuàng)作日期和聯(lián)系信息13、什么是SVG?【僅供參考】

SVG即可縮放失量圖形(ScalableVectorGraphics)。它是基于文本的圖形語言,使用文本、線條、點(diǎn)等來繪制圖像,這使得它輕便、顯示迅速。14、rgba0和opacity的透明效果有什么不同?【僅供參考】

rgba()和opacity都能實現(xiàn)透明效果,但它們最大的不同是opacity作用于元素,并且可以設(shè)置元素內(nèi)所有內(nèi)容的透明度;而rgba()只作用于元素的顏色或其背景色(設(shè)置rgba透明的元素的子元素不會繼承透明效果)。15、1rem、1em、1vh、1px各自代表的含義?【僅供參考】

rem:rem是全部的長度都相對于根元素元素。通常做法是給html元素設(shè)置一個字體大小,然后其他元素的長度單位就為rem。

em:子元素字體大小的em是相對于父元素字體大小,元素的width/height/padding/margin用em的話是相對于該元素的font-size

vw/vh:全稱是ViewportWidth和ViewportHeight,視窗的寬度和高度,相當(dāng)于屏幕寬度和高度的1%,不過,處理寬度的時候%單位更合適,處理高度的話vh單位更好。

px:px像素(Pixel)。相對長度單位。像素px是相對于顯示器屏幕分辨率而言的。16、CSS中,自適應(yīng)的單位都有哪些?【僅供參考】

自適應(yīng)的單位有以下幾個

百分比:%

相對于視口寬度的單位:ww

相對于視口高度的單位:vh

相對于視口寬度或者高度(取決于哪個?。┑膯挝唬篤m

相對于父元素字體大小的單位:em

相對于根元素字體大小的單位:rem17、我們會在寫css的時候做一些標(biāo)簽選擇器的初始化樣式?為什么?比如:【僅供參考】

body,ul,ol,li,p,h1,h2,h3,h4,h5,h6,form,fieldset,table,td,img,div{margin:0;padding:0;border:0;}

body{background:#fff;color:#333;font-size:12px;margin-top:5px;font-family:"SimSun","宋體","ArialNarrow";}

ul,ol{list-style-type:none;}

select,input,img,select{vertical-align:middle;}

a{text-decoration:none;}

a:link{color:#009;}

a:visited{color:#800080;}

a:hover,a:active,a:focus{color:#c00;text-decoration:underline;}

為了保證默認(rèn)的標(biāo)簽樣式在不同瀏覽器能有一致的效果18、如何實現(xiàn)左邊固定寬,右邊自適應(yīng)布局【僅供參考】

//1.圣杯布局

<divid="container">

<divid="center"class="column"></div>

<divid="left"class="column"></div>

<divid="right"class="column"></div>

</div>

#container{

padding-left:200px;

padding-right:150px;

}

#container.column{

float:left;

}

#center{

width:100%;

}

#left{

width:200px;

margin-left:-100%;

position:relative;

right:200px;

}

#right{

width:150px;

margin-right:-150px;

}

//2.雙飛翼布局

<divid="container"class="column">

<divid="center"></div>

</div>

<divid="left"class="column"></div>

<divid="right"class="column"></div>

#container{

width:100%;

}

.column{

float:left;

}

#center{

margin-left:200px;

margin-right:150px;

}

#left{

width:200px;

margin-left:-100%;

}

#right{

width:150px;

margin-left:-150px;

}

//3.等高布局(假等高)互補(bǔ)的內(nèi)外邊距

.parent{

overflow:hidden;

}

.left,.right{

margin-bottom:-10000px;

padding-bottom:10000px;

}

//4.等高布局(真等高)彈性盒子

.parent{

display:flex;

}

.child{

flex:1;

}

//calc

<divid="left"class="column"></div>

<divid="center"class="column"></div>

<divid="right"class="column"></div>

.column{

float:left;

}

#left{

width:100px;

}

#right{

width:200px;

}

#center{

width:calc(100%-100px-200px);

}

//5.浮動

<divid="left"class="column"></div>

<divid="right"class="column"></div>

<divid="center"></div>

#left{

float:left;

width:100px;

}

#right{

float:right;

width:200px;

}

#center{

margin-left:100px;

margin-right:200px;

}19、line-height三種賦值方式有何區(qū)別?(帶單位、純數(shù)字、百分比)【僅供參考】

帶單位:px是固定值,而em會參考父元素font-size值計算自身的行高

純數(shù)字:會把比例傳遞給后代。例如,父級行高為1.5,子元素字體為18px,則子元素行高為1.5*18=27px

百分比:將計算后的值傳遞給后代20、標(biāo)準(zhǔn)盒子模型和IE(怪異)盒子模型理解多少?【僅供參考】

box-size:content-box是標(biāo)準(zhǔn)盒子模型,實際的區(qū)域是padding+border+content,content區(qū)域就是設(shè)置的元素寬度,padding和border會占用外部空間

box-size:border-box的話,元素的寬度為padding+border+content,元素設(shè)置了寬度,不會占用外部空間。二、JS/ES6/TS篇1、split()join()的區(qū)別【僅供參考】

split():以指定的字符分割字符串返回一個數(shù)組,字符串方法

join():以指定的字符連接數(shù)組中元素返回一個字符串,數(shù)組方法2、documentload事件和documentready事件的區(qū)別【僅供參考】

頁面加載完成有兩種事件

load是當(dāng)頁面所有資源全部加載完成后(包括DOM文檔樹,css文件,js文件,圖片資源等),執(zhí)行一個函數(shù)

問題:如果圖片資源較多,加載時間較長,onload后等待執(zhí)行的函數(shù)需要等待較長時間,所以一些效果可能受到影響

$(document).ready()是當(dāng)DOM文檔樹加載完成后執(zhí)行一個函數(shù)(不包含圖片,css等)所以會比load較快執(zhí)行

在原生的jS中不包括ready()這個方法,只有l(wèi)oad方法就是onload事件3、foo=foo||bar,這行代碼是什么意思?為什么要這樣寫?【僅供參考】

如果foo轉(zhuǎn)為false,則返回bar;否則直接返回foo

邏輯或:如果第一個值為true,直接返回第一個值;否則直接返回第二個值

邏輯與:如果第一個值為false,直接返回第一個值;否則返回第二個值4、基本數(shù)據(jù)類型和引用數(shù)據(jù)類型有什么區(qū)別?【僅供參考】

(1)變量直接賦值時:

基本數(shù)據(jù)類型賦值的是數(shù)據(jù)的副本,原數(shù)據(jù)的更改不會影響傳入后的數(shù)據(jù)。

引用數(shù)據(jù)類型賦值的是數(shù)據(jù)的引用地址,原數(shù)據(jù)的更改會影響傳入后的數(shù)據(jù)。

(2)兩者在內(nèi)存中的存儲位置:

基本數(shù)據(jù)類型存儲在棧中。

引用數(shù)據(jù)類型在棧中存儲了指針,該指針指向的數(shù)據(jù)實體存儲在堆中。5、null和undefined的區(qū)別?【僅供參考】

null表示一個對象被定義了,值為“空值”;

undefined表示不存在這個值。

(1)變量被聲明了,但沒有賦值時,就等于undefined。(2)調(diào)用函數(shù)時,應(yīng)該提供的參數(shù)沒有提供,該參數(shù)等于undefined。(3)對象沒有賦值的屬性,該屬性的值為undefined。(4)函數(shù)沒有返回值時,默認(rèn)返回undefined。6、“===”、“==”的區(qū)別?【僅供參考】

==,當(dāng)且僅當(dāng)兩個運(yùn)算數(shù)相等時,它返回true,即不檢查數(shù)據(jù)類型

===,只有在無需類型轉(zhuǎn)換運(yùn)算數(shù)就相等的情況下,才返回true,需要檢查數(shù)據(jù)類型7、target和currentTarget區(qū)別【僅供參考】

都是事件對象上的屬性

event.target:返回觸發(fā)事件的元素

event.currentTarget:返回綁定事件的元素(相當(dāng)于事件中this)8、數(shù)組方法pop()push()unshift()shift()【僅供參考】

pop()尾部刪除

push()尾部添加

unshift()頭部添加

shift()頭部刪除9、怎么樣刪除一個對象的屬性【僅供參考】

delete對象.屬性名10、可以大量節(jié)省內(nèi)存占用,減少事件注冊【僅供參考】

2.可以實現(xiàn)當(dāng)新增子對象時,無需再對其進(jìn)行事件綁定11、請解釋一下什么是重排與重繪?【僅供參考】

重排:當(dāng)改變dom結(jié)構(gòu)的時候,就會從dom樹開始從新渲染頁面,這過程叫重排比如添加或者刪除可見的DOM元素、元素尺寸改變、元素內(nèi)容改變、瀏覽器窗口尺寸改變等等

重繪:當(dāng)改變樣式(不改變幾何結(jié)構(gòu))的時候,它會從render樹開始重新開始渲染頁面,這過程叫重繪,比如改變顏色,透明等12、請說出三種減低頁面加載時間的方法【僅供參考】

壓縮css、js文件

合并js、css文件,減少http請求(精靈圖)

外部js、css文件放在最底下

減少dom操作,盡可能用變量替代不必要的dom操作13、offsetWidth/offsetHeight,clientWidth/clientHeight,scrollWidth/scrollHeight的區(qū)別?【僅供參考】

offsetWidth/offsetHeight返回值包含content+padding+border+包含滾動條,效果與e.getBoundingClientRect()相同

clientWidth/clientHeight返回值只包含content+padding,如果有滾動條,也不包含滾動條

scrollWidth/scrollHeight返回值包含content+padding+溢出內(nèi)容的尺寸14、JavaScript是單線程的,瀏覽器是多進(jìn)程的【僅供參考】

每打開一個新網(wǎng)頁就會創(chuàng)建一個渲染進(jìn)程

渲染進(jìn)程是多線程的

負(fù)責(zé)頁面渲染的GUI渲染線程

負(fù)責(zé)JavaScript的執(zhí)行的JavaScript引擎線程,

負(fù)責(zé)瀏覽器事件循環(huán)的事件觸發(fā)線程,注意這不歸JavaScript引擎線程管

負(fù)責(zé)定時器的定時觸發(fā)器線程,setTimeout中低于4ms的時間間隔算為4ms

負(fù)責(zé)XMLHttpRequest的異步http請求線程

GUI渲染線程與JavaScript引擎線程是互斥的

單線程JavaScript是因為避免DOM渲染的沖突,webworker支持多線程,但是webworker不能訪問window對象,document對象等。15、什么是裝飾器,它們可以應(yīng)用于什么?【僅供參考】

裝飾器是一種特殊的聲明,它允許你通過使用@<name>注釋標(biāo)記來一次性修改類或類成員。每個裝飾器都必須引用一個將在運(yùn)行時評估的函數(shù)。

例如,裝飾器@sealed將對應(yīng)于sealed函數(shù)。任何標(biāo)有的@sealed都將用于評估sealed函數(shù)。

functionsealed(target){

//dosomethingwith'target'...

}

它們可以附加到:

類聲明

方法

配件

特性

參數(shù)

注意:默認(rèn)情況下不啟用裝飾器。要啟用它們,你必須experimentalDecorators從tsconfig.json文件或命令行編輯編譯器選項中的字段16、TypeScript中?.,??,!:,_,**等符號的含義?【僅供參考】

?.可選鏈

??類似與短路或,??避免了一些意外情況,0,NaN以及"",false被視為false值。只有undefind,null被視為false值。

!.在變量名后添加!,可以斷言排除undefined和null類型

_,聲明該函數(shù)將被傳遞一個參數(shù),但您并不關(guān)心它

!:待會分配這個變量,ts不要擔(dān)心

**求冪17、枚舉和常量枚舉的區(qū)別?【僅供參考】

枚舉會被編譯時會編譯成一個對象,可以被當(dāng)作對象使用

const枚舉會在typescript編譯期間被刪除,const枚舉成員在使用的地方會被內(nèi)聯(lián)進(jìn)來,避免額外的性能開銷18、什么時候應(yīng)該使用關(guān)鍵字unknown?【僅供參考】

unknown,如果你不知道預(yù)先期望哪種類型,但想稍后分配它,則應(yīng)該使用該any關(guān)鍵字,并且該關(guān)鍵字將不起作用。19、es6中對象新增的方法【僅供參考】

①object.assign()用于合并對象和淺拷貝

②object.keys()返回值是一個數(shù)組,數(shù)組包含了對象可遍歷屬性的所有key值(與for..in的區(qū)別:for...in會走原型鏈,他不會走原型鏈)

③object.values()返回值是一個數(shù)組,數(shù)組包含了目標(biāo)對象可遍歷的所有鍵值(與for...of的區(qū)別:返回值不一樣,for...of可以對遍歷的鍵值進(jìn)行額外操作,object.values()不行)

④object.entries()返回的是所有可遍歷屬性鍵和鍵值的數(shù)組20、設(shè)計一個對象,鍵名的類型至少包含一個symbol類型,并且實現(xiàn)遍歷所有key【僅供參考】

letname=Symbol('name');

letproduct={

[name]:"洗衣機(jī)",

"price":799

};

Reflect.ownKeys(product);三、Vue/React篇1、React中的狀態(tài)是什么?它是如何使用的?【僅供參考】

狀態(tài)是React組件的核心,是數(shù)據(jù)的來源,必須盡可能簡單?;旧蠣顟B(tài)是確定組件呈現(xiàn)和行為的對象。與props不同,它們是可變的,并創(chuàng)建動態(tài)和交互式組件??梢酝ㄟ^this.state()訪問它們2、什么是Props?【僅供參考】

Props是React中屬性的簡寫。它們是只讀組件,必須保持純,即不可變。它們總是在整個應(yīng)用中從父組件傳遞到子組件。子組件永遠(yuǎn)不能將prop送回父組件。這有助于維護(hù)單向數(shù)據(jù)流,通常用于呈現(xiàn)動態(tài)生成的數(shù)據(jù)3、常用的hooks有哪些?【僅供參考】

》useState:保存組件內(nèi)部狀態(tài)的函數(shù),提供了setState改變組件狀態(tài)。

》uesEffect:在函數(shù)組件中執(zhí)行副作用操作,componentDidMount,componentDidUpdate和componentWillUnmount。

負(fù)責(zé)對某些值進(jìn)行實時監(jiān)控。如果第二個可選參數(shù)為空,表明在第一次渲染時進(jìn)行。

如果是需要清除的副作用,一個return一鍵清除。【數(shù)據(jù)請求】

》useContext:跨組件傳值

》useReducer:useState的加強(qiáng)版,在某些場景下,useReducer會比useState更適用,例如state邏輯較復(fù)雜且包含多個子值,或者下一個state依賴于之前的state等。

》useCallback:和useEffect類似,把函數(shù)做為第一個參數(shù),把函數(shù)的依賴項作為第二個參數(shù)傳入,改回調(diào)函數(shù)只有在函數(shù)的依賴項發(fā)生改變時才會調(diào)用,返回的是一個回調(diào)函數(shù)。

》useMemo和uesCallback類似......返回的是一個值。

》useRefconstrefContainer=useRef(initialValue);

useRef返回一個可變的ref對象,其.current屬性被初始化為傳入的參數(shù)(initialValue)。返回的ref對象在組件的整個生命周期內(nèi)持續(xù)存在。

本質(zhì)上,useRef就像是可以在其.current屬性中保存一個可變值的“盒子”。

你應(yīng)該熟悉ref這一種訪問DOM的主要方式。如果你將ref對象以<divref={myRef}/>形式傳入組件,則無論該節(jié)點(diǎn)如何改變,React都會將ref對象的.current屬性設(shè)置為相應(yīng)的DOM節(jié)點(diǎn)。

然而,useRef()比ref屬性更有用。它可以<ahref="https:///p/515755713/edit#is-there-something-like-instance-variables">很方便地保存任何可變值,其類似于在class中使用實例字段的方式。

這是因為它創(chuàng)建的是一個普通Javascript對象。而useRef()和自建一個{current:...}對象的唯一區(qū)別是,useRef會在每次渲染時返回同一個ref對象。

請記住,當(dāng)ref對象內(nèi)容發(fā)生變化時,useRef并不會通知你。變更.current屬性不會引發(fā)組件重新渲染。如果想要在React綁定或解綁DOM節(jié)點(diǎn)的ref時運(yùn)行某些代碼,則需要使用回調(diào)ref來實現(xiàn)。

》useImperativeHandleuseImperativeHandle(ref,createHandle,[deps])

useImperativeHandle可以讓你在使用ref時自定義暴露給父組件的實例值。在大多數(shù)情況下,應(yīng)當(dāng)避免使用ref這樣的命令式代碼。useImperativeHandle應(yīng)當(dāng)與forwardRef一起使用:

functionFancyInput(props,ref){

constinputRef=useRef();

useImperativeHandle(ref,()=>({

focus:()=>{

inputRef.current.focus();

}

}));

return<inputref={inputRef}.../>;}

FancyInput=forwardRef(FancyInput);

在本例中,渲染<FancyInputref={inputRef}/>的父組件可以調(diào)用inputRef.current.focus()。

》useLayoutEffect

其函數(shù)簽名與useEffect相同,但它會在所有的DOM變更之后同步調(diào)用effect??梢允褂盟鼇碜x取DOM布局并同步觸發(fā)重渲染。在瀏覽器執(zhí)行繪制之前,useLayoutEffect內(nèi)部的更新計劃將被同步刷新。

盡可能使用標(biāo)準(zhǔn)的useEffect以避免阻塞視覺更新。

》useDebugValue可用于在React開發(fā)者工具中顯示自定義hook的標(biāo)簽。

》useDeferredValueconst[deferredValue]=useDeferredValue(value);

接受一個值并返回該值的新副本,該副本將推遲到更緊急的更新。如果當(dāng)前渲染是緊急更新的結(jié)果(如用戶輸入),React將返回以前的值,然后在緊急渲染完成后渲染新值。

useDeferredValue只延遲傳遞給它的值。

如果要防止子組件在緊急更新期間重新呈現(xiàn),還必須使用React來記憶該組件。記錄或反應(yīng)。使用備忘錄:

functionTypeahead(){

constquery=useSearchQuery('');

constdeferredQuery=useDeferredValue(query);

//Memonizing告訴React僅在延遲查詢更改時重新呈現(xiàn),

//當(dāng)查詢發(fā)生變化時不會。

constsuggestions=useMemo(()=>

<SearchSuggestionsquery={deferredQuery}/>,

[deferredQuery]

);

return(

<>

<SearchInputquery={query}/>

<Suspensefallback="Loadingresults...">

{suggestions}

</Suspense>

</>

);}

記住子對象會告訴React,它只需要在延遲查詢更改時重新呈現(xiàn)它們,而不需要在查詢更改時重新呈現(xiàn)它們。這個警告并不是useDeferredValue獨(dú)有的,它與使用去抖動或節(jié)流的類似鉤子使用的模式相同。

》useTransitionconst[isPending,startTransition]=useTransition();

返回轉(zhuǎn)換掛起狀態(tài)的有狀態(tài)值,以及啟動轉(zhuǎn)換的函數(shù)。

startTransition允許您將提供的回調(diào)中的更新標(biāo)記為轉(zhuǎn)換:

》useIdconstid=useId();

useId是一個鉤子,用于生成跨服務(wù)器和客戶端穩(wěn)定的唯一ID,同時避免不匹配。

例如,將id直接傳遞給需要它的元素:

》useSyncExternalStore

conststate=useSyncExternalStore(subscribe,getSnapshot[,getServerSnapshot]);

是一個推薦用于讀取和訂閱外部數(shù)據(jù)源的鉤子,其方式與選擇性水合和時間切片等并發(fā)渲染功能兼容。

》useInsertionEffectuseInsertionEffect(didUpdate);

簽名與useEffect相同,但它在所有DOM突變之前同步激發(fā)。在useLayoutEffect中讀取布局之前,使用此選項將樣式注入DOM。由于這個鉤子的作用域有限,所以這個鉤子不能訪問refs,也不能安排更新。4、useEffect的回調(diào)函數(shù)為什么無法使用async?【僅供參考】

React本身并不支持這么做,理由是effectfunction應(yīng)該返回一個銷毀函數(shù)(effect:是指return返回的cleanup函數(shù)),如果useEffect第一個參數(shù)傳入async,返回值則變成了Promise,會導(dǎo)致react在調(diào)用銷毀函數(shù)的時候報錯:function.applyisundefined。5、列出Redux的組件【僅供參考】

Action–這是一個用來描述發(fā)生了什么事情的對象。

Reducer–這是一個確定狀態(tài)將如何變化的地方。

Store–整個程序的狀態(tài)/對象樹保存在Store中。

View–只顯示Store提供的數(shù)據(jù)。6、類組件和函數(shù)組件之間的區(qū)別是什么?【僅供參考】

類組件可以使用其他特性,如狀態(tài)和生命周期鉤子,并且他有this

函數(shù)組件只能接收props渲染到頁面,無狀態(tài)組件,沒有this,不能使用生命周期鉤子

函數(shù)組件性能要高于類組件,因為類組件使用要實例化,而函數(shù)組件直接執(zhí)行取返回結(jié)果即可,為了提高性能,盡量使用函數(shù)組件7、常用的hooks【僅供參考】

useState:定義state的數(shù)據(jù),參數(shù)是初始化的數(shù)據(jù),返回值兩個值1.初始化值,2.修改的方法

useEffect:副作用函數(shù),顧名思義,副作用即只有使用過后才會產(chǎn)生副作用

當(dāng)作生命周期來使用:第二個參數(shù)如果沒寫的話,頁面一更新觸發(fā),compoentDidMountcompoentDidUpdate

第二個參數(shù)如果空數(shù)組的話,只執(zhí)行一次,compoentDidMount

數(shù)組中跟某些變量,當(dāng)作監(jiān)聽器來使用,監(jiān)聽數(shù)據(jù)的變化,

useEffect是一個副作用函數(shù),組件更新完成后觸發(fā)的函數(shù)

如果我們在useEffect返回一個函數(shù)的,組件被銷毀的時候觸發(fā)

useMemo:用來計算數(shù)據(jù),返回一個結(jié)果,監(jiān)聽數(shù)據(jù)的變化,第二個參數(shù)就是監(jiān)聽的數(shù)據(jù),具有緩存性

useMemo和useEffect相比較來說,useMemo是組件更新的時候觸發(fā)生命周期

useCallback:當(dāng)父組件向子組件傳遞函數(shù)的時候,父組件的改變會導(dǎo)致函數(shù)的重新調(diào)用產(chǎn)生新的作用域,所以還是會導(dǎo)致子組件的更新渲染,這個時候我們可以使用useCallback來緩存組件

useRef:相當(dāng)于createRef的使用,創(chuàng)建組件的屬性信息

useContext:相當(dāng)在函數(shù)組件中獲取context狀態(tài)數(shù)的內(nèi)容信息

useReducer:useReducer是用來彌補(bǔ)useState的補(bǔ)不足,可以把數(shù)據(jù)進(jìn)行集中式的管理,單獨(dú)處理數(shù)據(jù)的邏輯信息8、如何創(chuàng)建refs?【僅供參考】

通過React.createRef()創(chuàng)建的,并通過ref屬性附加到react元素,在構(gòu)造組件中,

通常將Refs分配給實例屬性,以便可以在整個組件中引用它們。9、react生命周期方法有哪些?【僅供參考】

componentWillMount:在渲染之前執(zhí)行,用于根組件中的App級配置。

componentDidMount:在第一次渲染之后執(zhí)行,可以在這里做AJAX請求,DOM的操作或狀態(tài)更新以及設(shè)置事件監(jiān)聽器。

componentWillReceiveProps:在初始化render的時候不會執(zhí)行,它會在組件接受到新的狀態(tài)(Props)時被觸發(fā),一般用于父組件狀態(tài)更新時子組件的重新渲染

shouldComponentUpdate:確定是否更新組件。默認(rèn)情況下,它返回true。如果確定在state或props更新后組件不需要在重新渲染,則可以返回false,這是一個提高性能的方法。

componentWillUpdate:在shouldComponentUpdate返回true確定要更新組件之前件之前執(zhí)行。

componentDidUpdate:它主要用于更新DOM以響應(yīng)props或state更改。

componentWillUnmount:它用于取消任何的網(wǎng)絡(luò)請求,或刪除與組件關(guān)聯(lián)的所有事件監(jiān)聽器。10、vue-cli工程升級vue版本【僅供參考】

在項目目錄里運(yùn)行npmupgradevuevue-template-compiler,不出意外的話,可以正常運(yùn)行和build。如果有任何問題,刪除node_modules文件夾然后重新運(yùn)行npmi即可。

(簡單的說就是升級vue和vue-template-compiler兩個插件)11、v-html與v-text區(qū)別【僅供參考】

答案:

v-html:可以轉(zhuǎn)義標(biāo)簽和渲染數(shù)據(jù)

v-text:不能轉(zhuǎn)義標(biāo)簽只能渲染數(shù)據(jù)

v-text展示效果:<strong>Hello</strong>Vue!

v-html展示效果:HelloVue!12、為什么避免v-if和v-for用在一起【僅供參考】

當(dāng)Vue處理指令時,v-for比v-if具有更高的優(yōu)先級,這意味著v-if將分別重復(fù)運(yùn)行于每個v-for循環(huán)中,帶來性能方面的浪費(fèi)。

我們可以把v-if移動到父級(容器)元素,不會再重復(fù)遍歷列表中的每個值。取而代之的是,我們只檢查它一次,且不會在v-if為否的時候運(yùn)算v-for。

或者在外層嵌套template(頁面渲染不生成dom節(jié)點(diǎn)),在這一層進(jìn)行v-if判斷,然后在內(nèi)部進(jìn)行v-for循環(huán)13、vue2和vue3的響應(yīng)式原理都有什么區(qū)別呢?【僅供參考】

vue2用的是Object.defindProperty但是vue3用的是Proxy

Object.defindProperty缺點(diǎn):

一次只能對一個屬性進(jìn)行監(jiān)聽,需要遍歷來對所有屬性監(jiān)聽

對于對象的新增屬性,需要手動監(jiān)聽

對于數(shù)組通過push、unshift方法增加的元素,也無法監(jiān)聽

Proxy就沒有這個問題,可以監(jiān)聽整個對象的數(shù)據(jù)變化,所以用vue3.0會用Proxy代替definedProperty。14、Vue框架怎么實現(xiàn)對象和數(shù)組的監(jiān)聽?【僅供參考】

Vue數(shù)據(jù)雙向綁定主要是指:數(shù)據(jù)變化更新視圖,視圖變化更新數(shù)據(jù)。

即:

輸入框內(nèi)容變化時,Data中的數(shù)據(jù)同步變化。即View=>Data的變化。

Data中的數(shù)據(jù)變化時,文本節(jié)點(diǎn)的內(nèi)容同步變化。即Data=>View的變化。

其中,View變化更新Data,可以通過事件監(jiān)聽的方式來實現(xiàn),所以Vue的數(shù)據(jù)雙向綁定的工作主要是如何根據(jù)Data變化更新View。

Vue主要通過以下4個步驟來實現(xiàn)數(shù)據(jù)雙向綁定的:

實現(xiàn)一個監(jiān)聽器Observer:對數(shù)據(jù)對象進(jìn)行遍歷,包括子屬性對象的屬性,利用Object.defineProperty()對屬性都加上setter和getter。這樣的話,給這個對象的某個值賦值,就會觸發(fā)setter,那么就能監(jiān)聽到了數(shù)據(jù)變化。

實現(xiàn)一個解析器Compile:解析Vue模板指令,將模板中的變量都替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個指令對應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動,收到通知,調(diào)用更新函數(shù)進(jìn)行數(shù)據(jù)更新。

實現(xiàn)一個訂閱者Watcher:Watcher訂閱者是Observer和Compile之間通信的橋梁,主要的任務(wù)是訂閱Observer中的屬性值變化的消息,當(dāng)收到屬性值變化的消息時,觸發(fā)解析器Compile中對應(yīng)的更新函數(shù)。

實現(xiàn)一個訂閱器Dep:訂閱器采用發(fā)布-訂閱設(shè)計模式,用來收集訂閱者Watcher,對監(jiān)聽器Observer和訂閱者Watcher進(jìn)行統(tǒng)一管理。15、Vuex是通過什么方式提供響應(yīng)式數(shù)據(jù)的?【僅供參考】

在Store構(gòu)造函數(shù)中通過newVue({})實現(xiàn)的。

利用Vue來監(jiān)聽state下的數(shù)據(jù)變化,

給狀態(tài)(數(shù)據(jù))添加getter、setter可以監(jiān)聽數(shù)據(jù)改變。16、v-cloak可以解決什么問題【僅供參考】

v-cloak指令解決vue屏幕閃屏

這個指令保持在元素上直到關(guān)聯(lián)實例結(jié)束編譯。和CSS規(guī)則如[v-cloak]{display:none}一起用時,這個指令可以隱藏未編譯的Mustache標(biāo)簽直到實例準(zhǔn)備完畢。17、0修改了組件的聲明方式,改成了類式的寫法,這樣使得和TypeScript的結(jié)合變得很容易。【僅供參考】

此外,vue的源碼也改用了TypeScript來寫。其實當(dāng)代碼的功能復(fù)雜之后,必須有一個靜態(tài)類型系統(tǒng)來做一些輔助管理。

現(xiàn)在vue3.0也全面改用TypeScript來重寫了,更是使得對外暴露的api更容易結(jié)合TypeScript。靜態(tài)類型系統(tǒng)對于復(fù)雜代碼的維護(hù)確實很有必要。

(4)其它方面的更改

vue3.0的改變是全面的,上面只涉及到主要的3個方面,還有一些其他的更改:

支持自定義渲染器,從而使得weex可以通過自定義渲染器的方式來擴(kuò)展,而不是直接fork源碼來改的方式。

支持Fragment(多個根節(jié)點(diǎn))和Protal(在dom其他部分渲染組建內(nèi)容)組件,針對一些特殊的場景做了處理。

基于treeshaking優(yōu)化,提供了更多的內(nèi)置功能。18、Vue組件間通信有哪幾種方式?【僅供參考】

Vue組件間通信是面試??嫉闹R點(diǎn)之一,這題有點(diǎn)類似于開放題,你回答出越多方法當(dāng)然越加分,表明你對Vue掌握的越熟練。

Vue組件間通信只要指以下3類通信:父子組件通信、隔代組件通信、兄弟組件通信,下面我們分別介紹每種通信方式且會說明此種方法可適用于哪類組件間通信。

(1)props/$emit適用父子組件通信

這種方法是Vue組件的基礎(chǔ),相信大部分同學(xué)耳聞能詳,所以此處就不舉例展開介紹。

(2)ref與$parent/$children適用父子組件通信

ref:如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子組件上,引用就指向組件實例

$parent/$children:訪問父/子實例

(3)EventBus($emit/$on)適用于父子、隔代、兄弟組件通信

這種方法通過一個空的Vue實例作為中央事件總線(事件中心),用它來觸發(fā)事件和監(jiān)聽事件,從而實現(xiàn)任何組件間的通信,包括父子、隔代、兄弟組件。

(4)$attrs/$listeners適用于隔代組件通信

$attrs:包含了父作用域中不被prop所識別(且獲取)的特性綁定(class和style除外)。當(dāng)一個組件沒有聲明任何prop時,這里會包含所有父作用域的綁定(class和style除外),并且可以通過v-bind="$attrs"傳入內(nèi)部組件。通常配合inheritAttrs選項一起使用。

$listeners:包含了父作用域中的(不含.native修飾器的)v-on事件監(jiān)聽器。它可以通過v-on="$listeners"傳入內(nèi)部組件

(5)provide/inject適用于隔代組件通信

祖先組件中通過provider來提供變量,然后在子孫組件中通過inject來注入變量。provide/injectAPI主要解決了跨級組件間的通信問題,不過它的使用場景,主要是子組件獲取上級組件的狀態(tài),跨級組件間建立了一種主動提供與依賴注入的關(guān)系。

(6)Vuex適用于父子、隔代、兄弟組件通信

Vuex是一個專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式。每一個Vuex應(yīng)用的核心就是store(倉庫)?!皊tore”基本上就是一個容器,它包含著你的應(yīng)用中大部分的狀態(tài)(state)。

Vuex的狀態(tài)存儲是響應(yīng)式的。當(dāng)Vue組件從store中讀取狀態(tài)的時候,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會相應(yīng)地得到高效更新。

改變store中的狀態(tài)的唯一途徑就是顯式地提交(commit)mutation。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化。19、什么是Proxy?【僅供參考】

Proxy:代理,是ES6新增的功能,可以理解為代理器(即由它代理某些操作)。

Proxy:對象用于定義或修改某些操作的自定義行為,可以在外界對目標(biāo)對象進(jìn)行訪問前,對外界的訪問進(jìn)行改寫。

Proxy是ES6中新增的一個特性JavaScript中用來表示由它來’代理’某些操作

Proxy是ES6中新增的一個特性,翻譯過來意思是"代理",用在這里表示由它來“代理”某些操作。Proxy讓我們能夠以簡潔易懂的方式控制外部對對象的訪問。其功能非常類似于設(shè)計模式中的代理模式。

Proxy可以理解成,在目標(biāo)對象之前架設(shè)一層“攔截”,外界對該對象的訪問,都必須先通過這層攔截,因此提供了一種機(jī)制,可以對外界的訪問進(jìn)行過濾和改寫。

使用Proxy的核心優(yōu)點(diǎn)是可以交由它來處理一些非核心邏輯(如:讀取或設(shè)置對象的某些屬性前記錄日志;設(shè)置對象的某些屬性值前,需要驗證;某些屬性的訪問控制等)。從而可以讓對象只需關(guān)注于核心邏輯,達(dá)到關(guān)注點(diǎn)分離,降低對象復(fù)雜度等目的。20、說一下v-slot的作用【僅供參考】

提供具名插槽或需要接收prop的插槽。四、Webpack/Rollup篇1、webpack的工作原理?【僅供參考】

WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語言(Sass,TypeScript等),并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用。在3.0出現(xiàn)后,Webpack還肩負(fù)起了優(yōu)化項目的責(zé)任。2、gulp和webpack區(qū)別【僅供參考】

gulp:是工具鏈、構(gòu)建工具,可以配合各種插件做js壓縮,css壓縮,less編譯替代手工實現(xiàn)自動化工作

(1)構(gòu)建工具

(2)自動化

(3)用于:提高效率——能夠優(yōu)化前端工作流程,提高工作效率

(4)自動刷新頁面,雪碧圖,壓縮css、js,編譯less,檢查語法等

(5)使用gulp可以配置你需要的插件,把以前需要手工做的事情讓它幫你做了

webpack:是文件打包工具,可以把項目的各種js文件、css文件等打包合并成一個或多個文件,主要用于模塊化方案,預(yù)編譯模塊的方案

(1)打包工具

(2)模塊化識別

(3)用于:編譯模塊代碼方案

兩者不是一個工具,不具有可比性,更不沖突3、有哪些常見的Loader?他們是解決什么問題的?【僅供參考】

file-loader:把文件輸出到一個文件夾中,在代碼中通過相對URL去引用輸出的文件

url-loader:和file-loader類似,但是能在文件很小的情況下以base64的方式把文件內(nèi)容注入到代碼中去

source-map-loader:加載額外的SourceMap文件,以方便斷點(diǎn)調(diào)試

image-loader:加載并且壓縮圖片文件

babel-loader:把ES6轉(zhuǎn)換成ES5

css-loader:加載CSS,支持模塊化、壓縮、文件導(dǎo)入等特性

style-loader:把CSS代碼注入到JavaScript中,通過DOM操作去加載CSS。

eslint-loader:通過ESLint檢查JavaScript代碼4、Webpack中Loader和Plugin的區(qū)別【僅供參考】

運(yùn)行時機(jī)1.loader運(yùn)行在編譯階段2.plugins在整個周期都起作用

使用方式Loader:1.下載2.使用Plugin:1.下載2.引用3.使用5、Webpack的基本功能有哪些?【僅供參考】

代碼轉(zhuǎn)換:TypeScript編譯成JavaScript、SCSS編譯成CSS等等

文件優(yōu)化:壓縮JavaScript、CSS、html代碼,壓縮合并圖片等

代碼分割:提取多個頁面的公共代碼、提取首屏不需要執(zhí)行部分的代碼讓其異步加載

模塊合并:在采用模塊化的項目有很多模塊和文件,需要構(gòu)建功能把模塊分類合并成一個文件

自動刷新:監(jiān)聽本地源代碼的變化,自動構(gòu)建,刷新瀏覽器

代碼校驗:在代碼被提交到倉庫前需要檢測代碼是否符合規(guī)范,以及單元測試是否通過

自動發(fā)布:更新完代碼后,自動構(gòu)建出線上發(fā)布代碼并傳輸給發(fā)布系統(tǒng)。6、什么是模熱更新?有什么優(yōu)點(diǎn)?【僅供參考】

模塊熱更新是webpack的一個功能,它可以使得代碼修改之后,不用刷新瀏覽器就可以更新。

在應(yīng)用過程中替換添加刪出模塊,無需重新加載整個頁面,是高級版的自動刷新瀏覽器。

優(yōu)點(diǎn):只更新變更內(nèi)容,以節(jié)省寶貴的開發(fā)時間。調(diào)整樣式更加快速,幾乎相當(dāng)于在瀏覽器中更改樣式7、npm打包時需要注意哪些?如何利用webpack來更好的構(gòu)建?【僅供參考】

Npm是目前最大的JavaScript模塊倉庫,里面有來自全世界開發(fā)者上傳的可復(fù)用模塊。

你可能只是JS模塊的使用者,但是有些情況你也會去選擇上傳自己開發(fā)的模塊。

關(guān)于NPM模塊上傳的方法可以去官網(wǎng)上進(jìn)行學(xué)習(xí),這里只講解如何利用webpack來構(gòu)建。

NPM模塊需要注意以下問題:

要支持CommonJS模塊化規(guī)范,所以要求打包后的最后結(jié)果也遵守該規(guī)則。

Npm模塊使用者的環(huán)境是不確定的,很有可能并不支持ES6,所以打包的最后結(jié)果應(yīng)該是采用ES5編寫的。并且如果ES5是經(jīng)過轉(zhuǎn)換的,請最好連同SourceMap一同上傳。

Npm包大小應(yīng)該是盡量?。ㄓ行﹤}庫會限制包大?。?/p>

發(fā)布的模塊不能將依賴的模塊也一同打包,應(yīng)該讓用戶選擇性的去自行安裝。這樣可以避免模塊應(yīng)用者再次打包時出現(xiàn)底層模塊被重復(fù)打包的情況。

UI組件類的模塊應(yīng)該將依賴的其它資源文件,例如.css文件也需要包含在發(fā)布的模塊里。8、webpack如何配置多入口文件?【僅供參考】

entry:{

home:resolve(__dirname,"src/home/index.js"),

about:resolve(__dirname,"src/about/index.js")

}

用于描述入口的對象。你可以使用如下屬性:

dependOn:當(dāng)前入口所依賴的入口。它們必須在該入口被加載前被加載。

filename:指定要輸出的文件名稱。

import:啟動時需加載的模塊。

library:指定library選項,為當(dāng)前entry構(gòu)建一個library。

runtime:運(yùn)行時chunk的名字。如果設(shè)置了,就會創(chuàng)建一個新的運(yùn)行時chunk。在webpack5.43.0之后可將其設(shè)為false以避免一個新的運(yùn)行時chunk。

publicPath:當(dāng)該入口的輸出文件在瀏覽器中被引用時,為它們指定一個公共URL地址9、plugin的作用【僅供參考】

plugin是一個類,類中有一個apply()方法,主要用于Plugin的安裝,可以在其中監(jiān)聽一些來自編譯器發(fā)出的事件,在合適的時機(jī)做一些事情。10、有哪些常見的Plugin?他們是解決什么問題的?【僅供參考】

html-webpack-plugin:可以復(fù)制一個有結(jié)構(gòu)的html文件,并自動引入打包輸出的所有資源(JS/CSS)

clean-webpack-plugin:重新打包自動清空dist目錄

mini-css-extract-plugin:提取js中的css成單獨(dú)文件

optimize-css-assets-webpack-plugin:壓縮css

uglifyjs-webpack-plugin:壓縮js

commons-chunk-plugin:提取公共代碼

define-plugin:定義環(huán)境變量11、常見Plugins【僅供參考】

HtmlWbpackPlugin自動在打包結(jié)束后生成html文件,并引入bundle.js

cleanwebPackPlugin打包自動刪除上次打包文件12、Webpack的打包過程/打包原理/構(gòu)建流程?【僅供參考】

初始化:啟動構(gòu)建,讀取與合并配置參數(shù),加載plugin,實例化Compiler

編譯:從Entry出發(fā),針對每個Module串行調(diào)用對應(yīng)的Loader去翻譯文件中的內(nèi)容,再找到該Module依賴的Module,遞歸的進(jìn)行編譯處理

輸出:將編譯后的Module組合成Chunk,將Chunk轉(zhuǎn)換成文件,輸出到文件系統(tǒng)中

細(xì)節(jié):

WebpackCLI通過yargs模塊解析CLI參數(shù),并轉(zhuǎn)化為配置對象option(單入口:Object,多入口:Array),調(diào)用webpack(option)創(chuàng)建compiler對象。

如果有option.plugin,則遍歷調(diào)用plugin.apply()來注冊plugin,

判斷是否開啟了watch,如果開啟則調(diào)用compiler.watch,否則調(diào)用compiler.run,開始構(gòu)建。

創(chuàng)建Compilation對象來收集全部資源和信息,然后觸發(fā)make鉤子。

make階段從入口開始遞歸所有依賴,

每次遍歷時調(diào)用對應(yīng)Loader翻譯文件中內(nèi)容,然后生成AST,遍歷AST找到下個依賴?yán)^續(xù)遞歸,

根據(jù)入口和模塊之間關(guān)系組裝chunk,輸出到dist中的一個文件內(nèi)。

在以上過程中,webpack會在特定的時間點(diǎn)(使用tapable模塊)廣播特定的事件,插件監(jiān)聽事件并執(zhí)行相應(yīng)的邏輯,并且插件可以調(diào)用webpack提供的api改變webpack的運(yùn)行結(jié)果13、webpack是解決什么問題而生的?【僅供參考】

如果像以前開發(fā)時一個html文件可能會引用十幾個js文件,而且順序還不能亂,因為它們存在依賴關(guān)系,同時對于ES6+等新的語法,less,sass等CSS預(yù)處理都不能很好的解決……,此時就需要一個處理這些問題的工具。14、loader的作用【僅供參考】

webpack中的loader是一個函數(shù),主要為了實現(xiàn)源碼的轉(zhuǎn)換,所以loader函數(shù)會以源碼作為參數(shù),比如,將ES6轉(zhuǎn)換為ES5,將less轉(zhuǎn)換為css,然后再將css轉(zhuǎn)換為js,以便能嵌入到html文件中。15、Plugin(插件)的作用是什么?【僅供參考】

Plugin是用來擴(kuò)展Webpack功能的,通過在構(gòu)建流程里注入鉤子實現(xiàn),它給Webpack帶來了很大的靈活性。

Webpack是通過plugins屬性來配置需要使用的插件列表的。plugins屬性是一個數(shù)組,里面的每一項都是插件的一個實例,在實例化一個組件時可以通過構(gòu)造函數(shù)傳入這個組件支持的配置屬性。16、webpack的構(gòu)建流程是什么?從讀取配置到輸出文件這個過程盡量說全。【僅供參考】

Webpack的運(yùn)行流程是一個串行的過程,從啟動到結(jié)束會依次執(zhí)行以下流程:

初始化參數(shù):從配置文件和Shell語句中讀取與合并參數(shù),得出最終的參數(shù);

開始編譯:用上一步得到的參數(shù)初始化Compiler對象,加載所有配置的插件,執(zhí)行對象的run方法開始執(zhí)行編譯;

確定入口:根據(jù)配置中的entry找出所有的入口文件;

編譯模塊:從入口文件出發(fā),調(diào)用所有配置的Loader對模塊進(jìn)行翻譯,再找出該模塊依賴的模塊,再遞歸本步驟直到所有入口依賴的文件都經(jīng)過了本步驟的處理;

完成模塊編譯:在經(jīng)過第4步使用Loader翻譯完所有模塊后,得到了每個模塊被翻譯后的最終內(nèi)容以及它們之間的依賴關(guān)系;

輸出資源:根據(jù)入口和模塊之間的依賴關(guān)系,組裝成一個個包含多個模塊的Chunk,再把每個Chunk轉(zhuǎn)換成一個單獨(dú)的文件加入到輸出列表,這步是可以修改輸出內(nèi)容的最后機(jī)會;

輸出完成:在確定好輸出內(nèi)容后,根據(jù)配置確定輸出的路徑和文件名,把文件內(nèi)容寫入到文件系統(tǒng)。

在以上過程中,Webpack會在特定的時間點(diǎn)廣播出特定的事件,插件在監(jiān)聽到感興趣的事件后會執(zhí)行特定的邏輯,并且插件可以調(diào)用Webpack提供的API改變Webpack的運(yùn)行結(jié)果。17、babel相關(guān):polyfill以及runtime區(qū)別,ESstage含義,preset–env作用等等【僅供參考】

polyfill以及runtime區(qū)別

babel-polyfill的原理是當(dāng)運(yùn)行環(huán)境中并沒有實現(xiàn)的一些方法,babel-polyfill會做兼容。

babel-runtime它是將es6編譯成es5去執(zhí)行。我們使用es6的語法來編寫,最終會通過babel-runtime編譯成es5.也就是說,不管瀏覽器是否支持ES6,只要是ES6的語法,它都會進(jìn)行轉(zhuǎn)碼成ES5.所以就有很多冗余的代碼。

babel-polyfill它是通過向全局對象和內(nèi)置對象的prototype上添加方法來實現(xiàn)的。比如運(yùn)行環(huán)境中不支持Atotype.find方法,引入polyfill,我們就可以使用es6方法來編寫了,但是缺點(diǎn)就是會造成全局空間污染。

babel-runtime:它不會污染全局對象和內(nèi)置對象的原型,比如說我們需要Promise,我們只需要importPromisefrom'babel-runtime/core-js/promise'即可,這樣不僅避免污染全局對象,而且可以減少不必要的代碼。

stage-x:指處于某一階段的js語言提案

Stage0-設(shè)想(Strawman):只是一個想法,可能有Babel插件。

Stage1-建議(Proposal):這是值得跟進(jìn)的。

Stage2-草案(Draft):初始規(guī)范。

Stage3-候選(Candidate):完成規(guī)范并在瀏覽器上初步實現(xiàn)。

Stage4-完成(Finished):將添加到下一個年度版本發(fā)布中。18、lazyloading(模塊懶加載)【僅供參考】

借助import()語法異步引入組件,實現(xiàn)文件懶加載:prefetch,preloading

webpack提倡多寫異步代碼,提升代碼利用率,從而提升頁面性能

先加載主業(yè)務(wù)文件,prefetch利用網(wǎng)絡(luò)空閑時間,異步加載組件

import(/*webpackPrefetch:true/‘LoginModal’);

preload和主業(yè)務(wù)文件一起加載,異步加載組件

import(/webpackPreload:true*/‘ChartingLibrary’);19、ExtractTextPlugin插件的作用【僅供參考】

ExtractTextPlugin插件的作用是提取出JavaScript代碼里的CSS到一個單獨(dú)的文件。

對此你可以通過插件的filename屬性,告訴插件輸出的CSS文件名稱是通過[name]_[contenthash:8].css字符串模版生成的,里面的[name]代表文件名稱,[contenthash:8]代表根據(jù)文件內(nèi)容算出的8位hash值,還有很多配置選項可以在ExtractTextPlugin的主頁上查到。20、webpack3和webpack4的區(qū)別【僅供參考】

mode/–mode參數(shù),新增了mode/–mode參數(shù)來表示是開發(fā)還是生產(chǎn)(development/production)production側(cè)重于打包后的文件大小,development側(cè)重于goujiansud移除loaders,必須使用rules(在3版本的時候loaders和rules是共存的但是到4的時候只允許使用rules)移除了CommonsChunkPlugin(提取公共代碼),用optimization.splitChunks和optimization.runtimeChunk來代替支持es6的方式導(dǎo)入JSON文件,并且可以過濾無用的代碼五、性能/瀏覽器/其他篇1、緩存機(jī)制,主要是問304和強(qiáng)緩存,協(xié)商緩存【僅供參考】

cache-control:max-age="xxxx"算是強(qiáng)緩存的一個標(biāo)志。強(qiáng)緩存(max-age="設(shè)置緩存的時間")。意思就是只要時間沒超時,就會在請求的時使用緩存的文件,不會重新請求資源。瀏覽器先根據(jù)這個資源的http頭信息來判斷是否命中強(qiáng)緩存。如果命中則直接加在緩存中的資源,并不會將請求發(fā)送到服務(wù)器。(強(qiáng)緩存)

若未命中強(qiáng)緩存,則瀏覽器會將請求發(fā)送至服務(wù)器。服務(wù)器根據(jù)http頭信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match來判斷是否命中協(xié)商緩存。如果命中,則http返回碼為304,瀏覽器從緩存中加載資源(協(xié)商緩存)

如果未命中協(xié)商緩存,則服務(wù)器會將完整的資源返回給瀏覽器,瀏覽器加載新資源,并更新緩存。(新的請求)

協(xié)商緩存:它的觸發(fā)條件有兩點(diǎn)、

第一點(diǎn)是Cache-Control的值為no-cache,則會促發(fā)協(xié)商緩存。

第二點(diǎn)是max-age過期了,觸發(fā)協(xié)商緩存。

后端需要怎么設(shè)置

以nodejs為例,如果需要瀏覽器強(qiáng)緩存,可以這樣設(shè)置:

res.setHeader('Cache-Control','public,max-age=xxx');

如果需要協(xié)商緩存,則可以這樣設(shè)置:

res.setHeader('Cache-Control','public,max-age=0');

res.setHeader('Last-Modified',xxx);

res.setHeader('ETag',xxx);2、如何優(yōu)化服務(wù)器端的接口?【僅供參考】

具體方法如下。

(1)接口合并:如果一個頁面需要請求兩部分以上的數(shù)據(jù)接口,則建議合并成一個以減少HTTP請求數(shù)。

(2)減少數(shù)據(jù)量:去掉接口返回的數(shù)據(jù)中不需要的數(shù)據(jù)。

(3)緩存數(shù)據(jù):首次加載請求后,緩存數(shù)據(jù);對于非首次請求,優(yōu)先使用上次請求的數(shù)據(jù),這樣可以提升非首次請求的響應(yīng)速度。3、瀏覽器線程有哪些:【僅供參考】

瀏覽器的渲染進(jìn)程是多線程的。js是阻塞單線程的。

瀏覽器包含有以下線程:

1.GUI渲染線程

負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。

當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行

注意,GUI渲染線程與JS引擎線程是互斥的,當(dāng)JS引擎執(zhí)行時GUI線程會被掛起(相當(dāng)于被凍結(jié)了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行。

2.JS引擎線程

也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎)

JS引擎線程負(fù)責(zé)解析Javascript腳本,運(yùn)行代碼。

JS引擎一直等待著任務(wù)隊列中任務(wù)的到來,然后加以處理,一個Tab頁(renderer進(jìn)程)中無論什么時候都只有一個JS線程在運(yùn)行JS程序

同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時間過長,這樣就會造成頁面的渲染不連貫,導(dǎo)致頁面渲染加載阻塞。

3.事件觸發(fā)線程

歸屬于瀏覽器而不是JS引擎,用來控制事件循環(huán)(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助)

當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(也可來自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點(diǎn)擊、AJAX異步請求等),會將對應(yīng)任務(wù)添加到事件線程中

當(dāng)對應(yīng)的事件符合觸發(fā)條件被觸發(fā)時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理

注意,由于JS的單線程關(guān)系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當(dāng)JS引擎空閑時才會去執(zhí)行)

4.定時觸發(fā)器線程

傳說中的setInterval與setTimeout所在線程

瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的,(因為JavaScript引擎是單線程的,如果處于阻塞線程狀態(tài)就會影響記計時的準(zhǔn)確)

因此通過單獨(dú)線程來計時并觸發(fā)定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執(zhí)行)

注意,W3C在HTML標(biāo)準(zhǔn)中規(guī)定,規(guī)定要求setTimeout中低于4ms的時間間隔算為4ms。

5.異步http請求線程

在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求

將檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個回調(diào)再放入事件隊列中。再由JavaScript引擎執(zhí)行。4、HTTP和HTTPS,為什么HTTPS安全?【僅供參考】

HTTP協(xié)議通常承載與TCP協(xié)議之上,在HTTP和TCP之間添加一個安全協(xié)議層(SSL或TSL),這個時候,就成了我們常說的HTTPS

默認(rèn)HTTP的端口號為80,HTTPS的端口號為443

因為網(wǎng)絡(luò)請求需要中間有很多的服務(wù)器路由的轉(zhuǎn)發(fā),中間的節(jié)點(diǎn)都可能篡改信息,而如果使用HTTPS,密鑰在你和終點(diǎn)站才有,https之所有說比http安全,是因為他利用ssl/tls協(xié)議傳輸。包含證書,流量轉(zhuǎn)發(fā),負(fù)載均衡,頁面適配,瀏覽器適配,refer傳遞等,保障了傳輸過程的安全性5、移動端性能優(yōu)化?【僅供參考】

盡量使用css3動畫,開啟硬件加速

適當(dāng)使用touch時間代替click時間

避免使用css3漸變陰影效果

可以用transform:translateZ(0)來開啟硬件加速

不濫用float。float在渲染時計算量比較大,盡量減少使用

不濫用web字體。web字體需要下載,解析,重繪當(dāng)前頁面

合理使用requestAnimationFrame動畫代替setTimeout

css中的屬性(css3t

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論