最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

前端面試題2022.08.08最新,持續(xù)更新中

2022-08-07 14:32 作者:安哥說(shuō)前端  | 我要投稿

如需pdf請(qǐng)?jiān)L問(wèn)https://chenjunan.top/detail/Detail?id=7

# 前端優(yōu)化性能的方法

* 壓縮字體文件 使用 fontmin-webpack 插件對(duì)字體文件進(jìn)行壓縮

* 減少 HTTP 請(qǐng)求

* 使用字體圖標(biāo) iconfont 代替圖片圖標(biāo)

* 使用 webp 格式的圖片

* 減少重繪重排

* 使用事件委托

* 使用 Web Workers

# html + css

## 1. HTML和CCS3新增那些內(nèi)容?

* 廣義上的html5指的是最新一代前端開(kāi)發(fā)技術(shù)的總稱(chēng),包括html5,CSS3,新增的webAPI。

* Html中新增了:header,footer,main,nav等語(yǔ)義化標(biāo)簽,新增了video,audio,canvas畫(huà)布。新增了一些標(biāo)簽屬性,例如input的placeholder。

* Css3中新增了:圓角,陰影,濾鏡,vwvh單位,flex布局,媒體查詢(xún),過(guò)度和動(dòng)畫(huà),偽類(lèi)。線(xiàn)性漸變

* webAPI新增了:localStorage和sessionStorage,querySelector,webSocket,requestAnimationFrame,Worker(類(lèi)似分線(xiàn)程),地理位置。

## 2. 什么是HTML語(yǔ)義化?HTML語(yǔ)義化的好處是什么?

* html語(yǔ)義化讓頁(yè)面的內(nèi)容結(jié)構(gòu)化,結(jié)構(gòu)更清晰,便于對(duì)瀏覽器、搜索引擎解析;

即使在沒(méi)有樣式CSS情況下也以一種文檔格式顯示,并且是容易閱讀的;

搜索引擎的爬蟲(chóng)也依賴(lài)于HTML標(biāo)記來(lái)確定上下文和各個(gè)關(guān)鍵字的權(quán)重;

* 使閱讀源代碼的人對(duì)網(wǎng)站更容易將網(wǎng)站分塊,便于閱讀維護(hù)理解。

## 3. 前端頁(yè)面中動(dòng)畫(huà)都有那些實(shí)現(xiàn)方式,各自分別使用那些使用場(chǎng)景

* Transition:簡(jiǎn)單的動(dòng)畫(huà),只需要在兩個(gè)狀態(tài)之間變化的動(dòng)畫(huà)。

* keyframeAnimation:適合需要在多個(gè)狀態(tài)連續(xù)進(jìn)行的動(dòng)畫(huà)。

* js動(dòng)畫(huà):功能最強(qiáng)的動(dòng)畫(huà),但是效率最低。

## 4. 怪異和模型和盒模型的區(qū)別

* 在標(biāo)準(zhǔn)模式下,塊的總寬度= width + margin(左右) + padding(左右) + border(左右)

* 怪異模式下,塊的總寬度= width + margin(左右)(即width已經(jīng)包含了padding和border值)

* box-sizing來(lái)設(shè)置盒子屬性

* * content-box (默認(rèn))寬度盒高度即為元素內(nèi)容區(qū),再內(nèi)容區(qū)之外加padding、border、margin(標(biāo)準(zhǔn)盒模型)

* box-sizing 屬性為border-box時(shí),設(shè)置的寬度和高度是元素的邊框盒,此時(shí),為元素設(shè)置的padding和border也包含其中,content的實(shí)際大小為寬高減去內(nèi)邊距和邊框的大小。(怪異盒模型)

* box-sizing屬性為inheri時(shí),該元素繼承父元素的box-sizing屬性。

## 5. css3中transtion和animation的區(qū)別

* transition只有開(kāi)始和結(jié)束兩個(gè)狀態(tài),并且需要通過(guò)事件觸發(fā)

* animation可以通過(guò)定義關(guān)鍵幀指定多個(gè)動(dòng)畫(huà)狀態(tài),可以自動(dòng)播放

## 6. 頁(yè)面中常用那些單位,有什么區(qū)別

* px 以物理像素為基準(zhǔn)

* em以當(dāng)前元素font-size為基準(zhǔn)

* rem以html font-size為基準(zhǔn)

* vw/vh以瀏覽器窗口寬高為基準(zhǔn) 100vw=瀏覽器窗口寬度

* rpx 適用于小程序或uniapp中可以實(shí)現(xiàn)自適應(yīng) 750rpx=屏幕寬度

## 7. 怎么實(shí)現(xiàn)元素上下左右都居中?

* 實(shí)現(xiàn)元素本身內(nèi)容居中:text-align:center+行高。

* 實(shí)現(xiàn)子元素在父元素中居中:絕對(duì)定位 + 上下左右設(shè)置 0 + margin:auto。

## 8. 網(wǎng)頁(yè)性能優(yōu)化方案?

* 減少http請(qǐng)求次數(shù):CSS 精靈圖 , JS、CSS源碼壓縮、圖片大小控制合適;網(wǎng)頁(yè)Gzip,CDN托管,data緩存 ,圖片服務(wù)器。

* 前端模板 JS+數(shù)據(jù),減少由于HTML標(biāo)簽導(dǎo)致的帶寬浪費(fèi),前端用變量保存AJAX請(qǐng)求結(jié)果,每次操作本地變量,不用請(qǐng)求,減少請(qǐng)求次數(shù)

* 用innerHTML代替DOM操作,減少DOM操作次數(shù),優(yōu)化javascript性能。

* 當(dāng)需要設(shè)置的樣式很多時(shí)設(shè)置className而不是直接操作style。

* 少用全局變量、緩存DOM節(jié)點(diǎn)查找的結(jié)果。減少I(mǎi)O讀取操作。

* 避免使用CSS Expression(css表達(dá)式)又稱(chēng)Dynamic properties(動(dòng)態(tài)屬性)。

* 圖片預(yù)加載,將樣式表放在頂部,將腳本放在底部 加上時(shí)間戳。

## 9. < link>和@import導(dǎo)入樣式的區(qū)別

* link是XHTML標(biāo)簽,除了加載CSS外,還可以定義RSS等其他事務(wù);@import屬于CSS范疇,只能加載CSS。

* link引用CSS時(shí),在頁(yè)面載入時(shí)同時(shí)加載;@import需要頁(yè)面網(wǎng)頁(yè)完全載入以后加載。

* link是XHTML標(biāo)簽,無(wú)兼容問(wèn)題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。

* link支持使用Javascript控制DOM去改變樣式;而@import不支持。

## 10. display: flex;

- flex-direction 決定主軸的方向

- * `row`(默認(rèn)值):主軸為水平方向,起點(diǎn)在左端。

* `row-reverse`:主軸為水平方向,起點(diǎn)在右端。

* `column`:主軸為垂直方向,起點(diǎn)在上沿。

* `column-reverse`:主軸為垂直方向,起點(diǎn)在下沿。

- flex-wrap 決定換行

- * `nowrap`(默認(rèn)):不換行。

* `wrap`:換行,第一行在上方。

* `wrap-reverse`:換行,第一行在下方。

- flex-flow flex-direction屬性和flex-wrap屬性的簡(jiǎn)寫(xiě)形式,默認(rèn)值為row nowrap。

- justify-content 主軸上的對(duì)齊方式。

- * `flex-start`(默認(rèn)值):左對(duì)齊

* `flex-end`:右對(duì)齊

* `center`: 居中

* `space-between`:兩端對(duì)齊,項(xiàng)目之間的間隔都相等。

* `space-around`:每個(gè)項(xiàng)目?jī)蓚?cè)的間隔相等。所以,項(xiàng)目之間的間隔比項(xiàng)目與邊框的間隔大一倍。

- align-items 交叉軸上的對(duì)齊方式。

- * `flex-start`:交叉軸的起點(diǎn)對(duì)齊。

* `flex-end`:交叉軸的終點(diǎn)對(duì)齊。

* `center`:交叉軸的中點(diǎn)對(duì)齊。

* `baseline`: 項(xiàng)目的第一行文字的基線(xiàn)對(duì)齊。

* `stretch`(默認(rèn)值):如果項(xiàng)目未設(shè)置高度或設(shè)為auto,將占滿(mǎn)整個(gè)容器的高度。

- align-content 多根軸線(xiàn)的對(duì)齊方式。如果項(xiàng)目只有一根軸線(xiàn),該屬性不起作用。

- * `flex-start`:與交叉軸的起點(diǎn)對(duì)齊。

* `flex-end`:與交叉軸的終點(diǎn)對(duì)齊。

* `center`:與交叉軸的中點(diǎn)對(duì)齊。

* `space-between`:與交叉軸兩端對(duì)齊,軸線(xiàn)之間的間隔平均分布。

* `space-around`:每根軸線(xiàn)兩側(cè)的間隔都相等。所以,軸線(xiàn)之間的間隔比軸線(xiàn)與邊框的間隔大一倍。

* `stretch`(默認(rèn)值):軸線(xiàn)占滿(mǎn)整個(gè)交叉軸。

- 以下6個(gè)屬性設(shè)置在項(xiàng)目上。

- * `order`:屬性定義項(xiàng)目的排列順序。數(shù)值越小,排列越靠前,默認(rèn)為0。

* `flex-grow`: 定義項(xiàng)目的放大比例,默認(rèn)為`0`,即如果存在剩余空間,也不放大。

* `flex-shrink`: 定義了項(xiàng)目的縮小比例,默認(rèn)為1,即如果空間不足,該項(xiàng)目將縮小。

* `flex-basis`: 定義了在分配多余空間之前,項(xiàng)目占據(jù)的主軸空間(main size)。瀏覽器根據(jù)這個(gè)屬性,計(jì)算主軸是否有多余空間。它的默認(rèn)值為`auto`,即項(xiàng)目的本來(lái)大小。

* `flex`: `flex-grow`, `flex-shrink` 和 `flex-basis`的簡(jiǎn)寫(xiě),默認(rèn)值為`0 1 auto`。后兩個(gè)屬性可選。

* `align-self`:允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對(duì)齊方式,可覆蓋`align-items`屬性。默認(rèn)值為`auto`,表示繼承父元素的`align-items`屬性,如果沒(méi)有父元素,則等同于`stretch`。

## 11. 重繪和回流

* 重繪(**repaint**):當(dāng)**元素樣式的改變不影響頁(yè)面布局時(shí)**,比如元素的**顏色**,瀏覽器將對(duì)元素進(jìn)行的更新,稱(chēng)之為重繪。

* * 常見(jiàn)的重繪操作有:改變?cè)仡伾?,改變?cè)乇尘吧?……

* 回流(**reflow**):也叫做**重排**。當(dāng)**元素的尺寸或者位置發(fā)生了變化**,就需要重新計(jì)算渲染樹(shù),這就是回流,比如元素的**寬高**、**位置**,瀏覽器會(huì)重新渲染頁(yè)面,稱(chēng)為回流,又叫重排(layout)。

* 關(guān)系:**回流必定會(huì)觸發(fā)重繪,重繪不一定會(huì)觸發(fā)回流。重繪的開(kāi)銷(xiāo)較小,回流的代價(jià)較高**。

## 11. 瀏覽器渲染的原理

1. 處理 `HTML` 并構(gòu)建 `DOM` 樹(shù)。

2. 處理 `CSS`構(gòu)建 `CSSOM` 樹(shù)。

3. 將 `DOM` 與 `CSSOM` 合并成一個(gè)渲染樹(shù)。

4. 根據(jù)渲染樹(shù)來(lái)布局,計(jì)算每個(gè)節(jié)點(diǎn)的位置。

5. 調(diào)用 `GPU` 繪制,合成圖層,顯示在屏幕上

## 12. git 常用的命令

* 查看 git 版本: git --version

* 設(shè)置用戶(hù)簽名:git config --global user.name 用戶(hù)名

* 設(shè)置用戶(hù)簽名:git config --global user.email 郵箱

* 初始化本地庫(kù):git init

* 查看本地庫(kù)狀態(tài):git status

* 添加到緩存區(qū):git add 文件名

* 提交到本地庫(kù):git commit -m “日志信息” 文件名

* 查看歷史記錄:git reflog

* 版本穿梭:git reset --hard 版本號(hào)

* 推送版本:git push origin master 將本地庫(kù)儲(chǔ)存的代碼推送到遠(yuǎn)程庫(kù)

* 拉取:git pull origin master 將遠(yuǎn)程庫(kù)更新拉取到本地庫(kù)

* 查看提交歷史版本:git log

* 查看緩存區(qū)文件:git ls-files

* 查看分支:git branch

* 創(chuàng)建分支:git branch 分支名

* 將某個(gè)分支合并到當(dāng)前分支:git merge 分支名

* 查看分支記錄:git reflog 分支名

* 從遠(yuǎn)程倉(cāng)庫(kù)拉取代碼:git clone 遠(yuǎn)程庫(kù)的地址(./1.png)

## css 可以繼承的屬性

行高,color,關(guān)于字體的,關(guān)于文本的,列表布局,光標(biāo)屬性,元素可見(jiàn)型

# JavaScript

## 1. Js數(shù)據(jù)類(lèi)型有那些?

* 數(shù)值、字符串、布爾、undefined、null、數(shù)組、對(duì)象、函數(shù)

## 2. 引用類(lèi)型和值類(lèi)型的區(qū)別

* 值類(lèi)型存在于棧中, 存取速度快 引用類(lèi)型存在于堆,存取速度慢

* 值類(lèi)型復(fù)制的是值本身 引用類(lèi)型復(fù)制的是指向?qū)ο蟮闹羔?/p>

* 值類(lèi)型結(jié)構(gòu)簡(jiǎn)單只包含基本數(shù)據(jù), 引用類(lèi)型結(jié)構(gòu)復(fù)雜,可以實(shí)現(xiàn)多層嵌套

## 3. 判斷數(shù)據(jù)類(lèi)型的方法

**typeof** **instanceof** **constructor** **Object.prototype.toString.call()**

* **typeof**:只能判斷基本數(shù)據(jù)類(lèi)型,不能判端引用數(shù)據(jù)類(lèi)型

* **instanceof** :**只能正確判斷引用數(shù)據(jù)類(lèi)型**,而不能判斷基本數(shù)據(jù)類(lèi)型。`instanceof` 運(yùn)算符可以用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 `prototype` 屬性。

* **constructor**:有兩個(gè)作用,一是判斷數(shù)據(jù)的類(lèi)型,二是對(duì)象實(shí)例通過(guò) `constrcutor` 對(duì)象訪(fǎng)問(wèn)它的構(gòu)造函數(shù)。需要注意,如果創(chuàng)建一個(gè)對(duì)象來(lái)改變它的原型,`constructor`就不能用來(lái)判斷數(shù)據(jù)類(lèi)型了:

* **Object.prototype.toString.call()**:使用 Object 對(duì)象的原型方法 toString 來(lái)判斷數(shù)據(jù)類(lèi)型:

## 4. null 和 undefined 的區(qū)別?

首先 Undefined 和 Null 都是基本數(shù)據(jù)類(lèi)型,這兩個(gè)基本數(shù)據(jù)類(lèi)型分別都只有一個(gè)值,就是 undefined 和 null。

undefined 代表的含義是未定義,null 代表的含義是空對(duì)象。一般變量聲明了但還沒(méi)有定義的時(shí)候會(huì)返回 undefined,null

主要用于賦值給一些可能會(huì)返回對(duì)象的變量,作為初始化。

undefined 在 js 中不是一個(gè)保留字,這意味著我們可以使用 undefined 來(lái)作為一個(gè)變量名,這樣的做法是非常危險(xiǎn)的,它

會(huì)影響我們對(duì) undefined 值的判斷。但是我們可以通過(guò)一些方法獲得安全的 undefined 值,比如說(shuō) void 0。

當(dāng)我們對(duì)兩種類(lèi)型使用 typeof 進(jìn)行判斷的時(shí)候,Null 類(lèi)型化會(huì)返回 “object”,這是一個(gè)歷史遺留的問(wèn)題。當(dāng)我們使用雙等

號(hào)對(duì)兩種類(lèi)型的值進(jìn)行比較時(shí)會(huì)返回 true,使用三個(gè)等號(hào)時(shí)會(huì)返回 false。

## 5. Promise有那些使用場(chǎng)景?

* 在頁(yè)面打開(kāi)時(shí),要同時(shí)執(zhí)行多個(gè)ajax請(qǐng)求,可以使用promise處理多異步任務(wù)并發(fā)執(zhí)行

* 有些ajax請(qǐng)求之間存在依賴(lài)關(guān)系,需要順序執(zhí)行,造成結(jié)構(gòu)嵌套,可以使用promise解決異步任務(wù)多層嵌套的問(wèn)題, 實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

* 在項(xiàng)目中封裝網(wǎng)絡(luò)請(qǐng)求時(shí),使用peomise封裝ajax請(qǐng)求并返回peomise對(duì)象

* 兩個(gè)常用的靜態(tài)方法:

* * .all 所有都成功了才會(huì)返回

* .race 只要有一個(gè)成功或者失敗 都會(huì)返回

## <span style="color:red">6. Js函數(shù)中的this有那些指向?怎樣改變函數(shù)中this的指向?</span>

* 一般情況下,通過(guò)誰(shuí)調(diào)用,就指向誰(shuí)

* * 在js全局作用域, this指向window

* 在對(duì)象中,this指向這個(gè)對(duì)象本身

* 構(gòu)造函數(shù)中,this是正在創(chuàng)建的對(duì)象。

* 在事件函數(shù)中,this指向事件目標(biāo)

* (注意: 在計(jì)時(shí)器中this會(huì)被還原成window或置空,但箭頭函數(shù)可以保留this指向)

* 可用通過(guò)call(), apply(), bind()改變this的指向

* * apply() 和 call() 一樣,修改指向的同時(shí)調(diào)用函數(shù),唯一的區(qū)別是,傳參方式不同,aplly需要提供一個(gè)數(shù)組。

* bind() 修改this指向時(shí)不會(huì)調(diào)用函數(shù),而是生成一個(gè)新的函數(shù),新的函數(shù)和原函數(shù)代碼一樣,但是里面的this是綁定過(guò)的。

## <span style="color:red">7. 什么是原型和原型鏈?</span>

Js中的對(duì)象都有一個(gè)屬性叫做__ptoto__(也是一個(gè)對(duì)象),表示對(duì)象的原型。當(dāng)訪(fǎng)問(wèn)對(duì)象中的屬性或方法時(shí),首先在對(duì)象本身中尋找,如果找不到則會(huì)在原型中尋找,原型中也找不到時(shí)會(huì)在原型的原型中尋找,直到最頂層為止。

js中的類(lèi)(構(gòu)造函數(shù))都有一個(gè)prototype的屬性,表示本類(lèi)的原型類(lèi)型,通過(guò)這個(gè)類(lèi)實(shí)例化的對(duì)象(這個(gè)構(gòu)造函數(shù)創(chuàng)建的對(duì)象), __proto__都指向本類(lèi)的prototype,從而實(shí)現(xiàn)了類(lèi)方法或?qū)傩缘墓蚕?。一個(gè)類(lèi)的prototype也是一個(gè)對(duì)象,它也有__proto__,把它的__proto__指向另一個(gè)類(lèi)的prototype時(shí),那么這個(gè)類(lèi)的對(duì)象就能訪(fǎng)問(wèn)另一個(gè)類(lèi)中的方法,從而實(shí)現(xiàn)了方法的繼承。

A類(lèi)的prototype指向另一個(gè)類(lèi)B,B的prototype又可以指向C,這種結(jié)構(gòu)叫做原型鏈。

## 8. new在執(zhí)行時(shí)會(huì)做四件事情:

* 在內(nèi)存中創(chuàng)建一個(gè)中間對(duì)象

* 將該中間對(duì)象的 propo 指向構(gòu)造函數(shù)原型

* 構(gòu)造函數(shù)的 this 指向中間對(duì)象

* 返回該中間對(duì)象也是就是返回了實(shí)例對(duì)象

## 9. Js原生Ajax實(shí)現(xiàn)流程?

* 創(chuàng)建XMLHttpRequest請(qǐng)求對(duì)象

* open方法指定請(qǐng)求方式、請(qǐng)求路徑、同步異步

* 設(shè)置響應(yīng)HTTP請(qǐng)求狀態(tài)變化的函數(shù)

* send方法發(fā)送請(qǐng)求

* 響應(yīng)成功使用JavaScript和DOM實(shí)現(xiàn)局部刷新

## 10. 閉包是什么?有什么作用?

* 當(dāng)一個(gè)函數(shù)A的作用域被內(nèi)部的B函數(shù)引用時(shí),A函數(shù)的作用域就會(huì)被B函數(shù)閉包,當(dāng)A函數(shù)執(zhí)行完畢時(shí),A函數(shù)的作用域也不會(huì)釋放。

* 閉包可以實(shí)現(xiàn)對(duì)象的私有屬性和私有方法。

* 閉包可以封裝變量,從簡(jiǎn)減少對(duì)全局作用域的污

* 總結(jié):**閉包并不會(huì)引起內(nèi)存泄漏,只是由于IE9 之前的版本對(duì)JScript對(duì)象和COM對(duì)象使用不同的垃圾收集,從而導(dǎo)致內(nèi)存無(wú)法進(jìn)行回收。**

## 11. 閉包的注意點(diǎn)

* 由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。

* 閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。

## 12. 作用域

當(dāng)你需要使用一個(gè)變量的時(shí)候首先在自己作用域內(nèi)部查找如果有就直接使用沒(méi)有的話(huà)就去上一級(jí)作用域查找 直到全局作用域都沒(méi)有那么就報(bào)錯(cuò)

## 13. 作用域鏈作用域鏈

一般情況下,變量取值到 創(chuàng)建 這個(gè)變量 的函數(shù)的作用域中取值

但是如果在當(dāng)前作用域中沒(méi)有查到值,就會(huì)向上級(jí)作用域去查,直到查到全局作用域,這么一個(gè)查找過(guò)程形成的鏈條就叫做作用域鏈。

## 14. 什么是函數(shù)防抖和函數(shù)節(jié)流?

* 函數(shù)防抖:對(duì)于頻繁觸發(fā)的事件,如果只希望其最后一次(或第一次)執(zhí)行綁定函數(shù)的執(zhí)行,則需要使用函數(shù)防抖。

* 函數(shù)節(jié)流:對(duì)于頻繁觸發(fā)的事件,希望其按照一定的頻率進(jìn)行綁定函數(shù)調(diào)用,則使用函數(shù)節(jié)流。

* 函數(shù)防抖和節(jié)流都可以通過(guò)settimeout實(shí)現(xiàn)。

## 15. 棧和隊(duì)列的區(qū)別是什么?js中怎樣實(shí)現(xiàn)棧結(jié)構(gòu)?

* 棧和隊(duì)列都是線(xiàn)型數(shù)據(jù)結(jié)構(gòu),棧只有一個(gè)入口,同時(shí)也是出口,所以數(shù)據(jù)遵循先進(jìn)后出,后進(jìn)先出的規(guī)則。隊(duì)列一側(cè)是入口,另一側(cè)是出口,所以數(shù)據(jù)先進(jìn)先出,后進(jìn)后出。

* Js中的數(shù)組可以實(shí)現(xiàn)棧和隊(duì)列。Push和pop方法是一對(duì)棧操作,push和shift是一對(duì)隊(duì)列操作。

## 16. 什么是深拷貝和淺拷貝?

* 淺拷貝就是只復(fù)制數(shù)組(對(duì)象)本身,而不復(fù)制其內(nèi)容(引用類(lèi)型的數(shù)據(jù)內(nèi)容),最終兩個(gè)數(shù)組中指向同一套數(shù)據(jù)。

* 深拷貝則是既賦值本身也賦值內(nèi)容。

Js中對(duì)于引用類(lèi)型的數(shù)據(jù),默認(rèn)進(jìn)行的都是淺拷貝。

## 17. 深拷貝的實(shí)現(xiàn)方法

* 遞歸

* JSON對(duì)象的兩個(gè)方法 序列化和反序列化

* JQuery中的extend()方法

深拷貝改變不會(huì)影響源數(shù)據(jù) 復(fù)制的是指針

## 18. 淺拷貝的實(shí)現(xiàn)方法

* 枚舉

* 數(shù)組合并

* 數(shù)組切割

* 解構(gòu)

淺拷貝改變數(shù)據(jù)會(huì)影響源數(shù)據(jù) 復(fù)制的是指針還有內(nèi)容

## 19. ES6中新增了那些特性?

* 箭頭函數(shù),字符串模板,let塊級(jí)作用域聲明方式,const常量,class聲明類(lèi),結(jié)構(gòu)賦值,Promise,ES6模塊化。

## 20. 箭頭函數(shù)和普通函數(shù)的區(qū)別

* 箭頭函數(shù)內(nèi)部this跟函數(shù)所在上下文this保持一致

* 沒(méi)有arguments參數(shù)集合,可以用rest替代

* 不能使用call、bind、apply來(lái)改變this的指向

## 21. 什么是立即執(zhí)行函數(shù)

立即執(zhí)行函數(shù)就是創(chuàng)建一個(gè)匿名函數(shù) 然后立馬執(zhí)行調(diào)用 它創(chuàng)建一個(gè)獨(dú)立的作用域 避免了全局污染 不用括號(hào)包起來(lái) 瀏覽器會(huì)報(bào)語(yǔ)法錯(cuò)誤()

(function(){alert('我是匿名函數(shù)')} ()) // 用括號(hào)把整個(gè)表達(dá)式包起來(lái) 或者(function(){alert('我是匿名函數(shù)')}) () //用括號(hào)把函數(shù)包起來(lái)

以一個(gè)著名的面試題為:

```javascript

var liList = ul.getElementsByTagName('li')

for(var i=0; i<6; i++){

liList[i].onclick = function(){

alert(i) // 為什么 alert 出來(lái)的總是 6,而不是 0、1、2、3、4、5

}

}

```

解決辦法

```javascript

var liList = ul.getElementsByTagName('li')

for(var i=0; i<6; i++){

!function(ii){

liList[ii].onclick = function(){

alert(ii) // 0、1、2、3、4、5

}

}(i)

}

```

## 22. 使用 axios 發(fā) ajax 請(qǐng)求無(wú)法攜帶 cookie,什么原因,如何解決?

* axios默認(rèn)跨域請(qǐng)求不使用憑證,當(dāng)服務(wù)器在響應(yīng)頭中設(shè)置了cookie后, axios會(huì)默認(rèn)隱藏這部分信息,

* 設(shè)置 **axios.defaults.withCredentials = true;**即可

## 23. Ajax 中 get和post 兩種請(qǐng)求方式的區(qū)別

* 運(yùn)行速度:get請(qǐng)求簡(jiǎn)單,運(yùn)行速度也更快(存在緩存);

* 緩存:get存在緩存(優(yōu):提升速度,缺:不能及時(shí)獲取最新數(shù)據(jù))post沒(méi)有緩存;

* 數(shù)據(jù)儲(chǔ)量:get有數(shù)據(jù)量的限制,post則沒(méi)有限制

* 數(shù)據(jù)安全:發(fā)送包含未知字符的用戶(hù)輸入時(shí),post比get 更穩(wěn)定也更可靠;數(shù)據(jù)安全:發(fā)送包含未知字符的用戶(hù)輸入時(shí),post比get 更穩(wěn)定也更可靠;

* 傳參方式:get參數(shù)拼接在url后,post放在send里面并且需要設(shè)置請(qǐng)求頭xmr.setRequestHeader("content-type","application/x-www-form-urlencoded"

## 24. cookie 和 localstorage 有什么區(qū)別?

* 都可以實(shí)現(xiàn)在用戶(hù)的瀏覽器中存儲(chǔ)一些數(shù)據(jù)。

* 不同:cookie是由服務(wù)端主導(dǎo)的,主要用于存儲(chǔ)用戶(hù)身份驗(yàn)證信息。localstorage是由前端js控制的,主要用于緩存業(yè)務(wù)邏輯數(shù)據(jù)。Cookie會(huì)隨著請(qǐng)求頭和響應(yīng)頭往返于服務(wù)器和瀏覽器之間。

## 25. localStorage、sessionStorage和cookie的區(qū)別?

* 本地存儲(chǔ)容量更大有5MB左右,cookie只有4KB

* 本地存儲(chǔ)沒(méi)有過(guò)期時(shí)間,localStorage持久保存,除非手動(dòng)清除,sessionStorage窗口關(guān)閉自動(dòng)清除

* cookie會(huì)在客戶(hù)端與服務(wù)器端之間往返,服務(wù)器端可以操作cookie,本地存儲(chǔ)只存儲(chǔ)于本地

## 26. cookie 和session 的區(qū)別?

* cookie數(shù)據(jù)存放在客戶(hù)的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。Session基于cookie。

* cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙

* session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪(fǎng)問(wèn)增多,會(huì)比較占用你服務(wù)器的性能

* 單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。

## 27. webSocket是什么?適用于哪些網(wǎng)站?

webSocket是一種雙工通信技術(shù),可以實(shí)現(xiàn)服務(wù)器主動(dòng)向客戶(hù)端發(fā)送數(shù)據(jù)。

一般適用于需要實(shí)時(shí)通信的網(wǎng)站, 比如人工客服服務(wù)和在線(xiàn)頁(yè)游等

## 28. webpack工具的功能是什么?

* Webpack是為前端開(kāi)發(fā)設(shè)計(jì)的自動(dòng)化打包工具,能夠?qū)?xiàng)目中的js、css、圖片等資源進(jìn)行打包(其中js可以直接打包,其他類(lèi)型資源需要各自對(duì)應(yīng)的loader支持),相比于傳統(tǒng)的grunt、gulp等構(gòu)建工具,webpack在打包js代碼時(shí),能夠識(shí)別多種模塊化語(yǔ)法,進(jìn)行模塊化打包。

* Webpack還可以配合腳手架工具構(gòu)建項(xiàng)目的框架

## 29. 什么是WebWorker?在哪些場(chǎng)景下需要使用WebWorker?

WebWorker是h5中新增的WebAPI,用于啟動(dòng)一個(gè)獨(dú)立的線(xiàn)程,主線(xiàn)程和分線(xiàn)程只能通過(guò)相互發(fā)送消息進(jìn)行通信。當(dāng)前端頁(yè)面中有耗時(shí)很長(zhǎng)的代碼需要執(zhí)行時(shí),可以放在worker中執(zhí)行,否則會(huì)卡塞主線(xiàn)程,影響用戶(hù)體驗(yàn)。

## 30. 什么是MVC和MVVM?

MVC:model-view-controller

MVVM:model-view-view-model,

MVC模式通過(guò)controller控制器協(xié)調(diào)model和view的交互,View 傳送指令到 Controller,Controller 完成業(yè)務(wù)邏輯后,要求 Model 改變狀態(tài),Model 將新的數(shù)據(jù)發(fā)送到 View,用戶(hù)得到反饋,所有通信都是單向的。

MVVM模式使用數(shù)據(jù)雙向綁定,model和view直接進(jìn)行交互。

## 31. get請(qǐng)求緩存怎么解決?

Get請(qǐng)求的數(shù)據(jù)會(huì)被緩存到瀏覽器本地, 重復(fù)發(fā)起同一個(gè)get請(qǐng)求,會(huì)把請(qǐng)求重定向到本地緩存獲取數(shù)據(jù)(請(qǐng)求狀態(tài)碼304)

在請(qǐng)求時(shí)添加時(shí)間戳,保證每次請(qǐng)求字段不同, 就不會(huì)被重定向到緩存

## 32. 什么是正則表達(dá)式? 如何使用?

正則表達(dá)式, regular expression 也叫規(guī)則表達(dá)式, 主要用于字符串的檢索判斷操作

如, 檢索一個(gè)字符串中是否包含一定規(guī)則的字符, 或判斷一個(gè)字符串是否符合一定規(guī)則

常用于用于登錄注冊(cè)時(shí)的賬號(hào),密碼,手機(jī)號(hào),郵箱等的驗(yàn)證

## 33. 宏任務(wù)和微任務(wù):

* 重點(diǎn)提示:

* * js中有同步代碼和異步代碼,同步代碼在主線(xiàn)程執(zhí)行,形成一個(gè)執(zhí)行棧,而異步代碼在任務(wù)隊(duì)列中執(zhí)行。

* js任務(wù)隊(duì)列中放置的有宏任務(wù)和微任務(wù),所以異步代碼有宏任務(wù)和微任務(wù)之分,像setTimeout,setInterval,xhr等是宏任務(wù),像Promise,asnyc等是微任務(wù)。

* 當(dāng)異步的宏任務(wù)和微任務(wù)在同一個(gè)任務(wù)隊(duì)列時(shí),先執(zhí)行微任務(wù),再執(zhí)行宏任務(wù)。

## 34. 什么是立即執(zhí)行函數(shù)?談?wù)勈裁词情]包?閉包的優(yōu)缺點(diǎn)?什么是全局污染?

* 立即執(zhí)行函數(shù)就是創(chuàng)建一個(gè)匿名函數(shù),然后馬上調(diào)用,它創(chuàng)建了一個(gè)獨(dú)立的作用域,避免了全局污染,(聲明全局變量、函數(shù)等時(shí),它們將進(jìn)入全局命名空間。除了性能/內(nèi)存問(wèn)題(這可能會(huì)出現(xiàn)),您可能會(huì)遇到不幸的名稱(chēng)沖突)

* 閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),在js中只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此閉包是定義在一個(gè)函數(shù)內(nèi)部的函數(shù)。在本質(zhì)上的話(huà),閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁.

* 閉包最大的有點(diǎn)就是可以讀取函數(shù)內(nèi)部的變量和讓這些變量始終保持在內(nèi)存中. 因?yàn)殚]包會(huì)讓函數(shù)變量保存在內(nèi)存中,內(nèi)存消耗大,如果濫用的話(huà),會(huì)讓頁(yè)面卡頓,內(nèi)存泄漏

## 35. 什么是繼承?js繼承方式有哪些?談?wù)劽恳环N繼承方式的特點(diǎn)?

* 繼承是為了子類(lèi)可以使用父類(lèi)的所有的功能 并且能對(duì)這些功能進(jìn)行擴(kuò)展

* 繼承方式有

1. 構(gòu)造函數(shù)繼承(call & apply)直接利用call 或者apply方法將父類(lèi)的構(gòu)造函數(shù)的this綁定為子類(lèi)構(gòu)造函數(shù)的this就可以

缺點(diǎn):是無(wú)法繼承原型鏈上的屬性和方法

2. 原型繼承 將子類(lèi)的原型掛載到父類(lèi)上;

缺點(diǎn):子類(lèi)new的實(shí)例 父類(lèi)的屬性沒(méi)有隔離 會(huì)互相影響

3. 組合繼承:組合上面的構(gòu)造函數(shù)與原型繼承的功能 call方法已經(jīng)拿到父類(lèi)的所有屬性 后面在使用原型時(shí)也會(huì)有父類(lèi)所有屬性

4. 寄生式繼承: 解決組合繼承重復(fù)屬性的問(wèn)題,直接將子類(lèi)的原型等于父類(lèi)的原型,或者是用Object.create繼承原型但不執(zhí)行父類(lèi)構(gòu)造函數(shù);

注意:處理子類(lèi)實(shí)例的 constructor 指向問(wèn)題,new Parent2()也有這個(gè)問(wèn)題;

5. class繼承 Class 的 Extends 繼承原理

補(bǔ)充:new與Object.create()區(qū)別

new創(chuàng)建一個(gè)對(duì)象,執(zhí)行構(gòu)造函數(shù)。

Object.create相當(dāng)于創(chuàng)建一個(gè)對(duì)象,但是不執(zhí)行構(gòu)造函數(shù)。

## 36. 你接觸過(guò)的異步方案有哪些?分別談?wù)劊?/p>

* 我經(jīng)常會(huì)用callback,promise和事件監(jiān)聽(tīng)的方式來(lái)處理異步

* callback就是一個(gè)函數(shù)被作為一個(gè)參數(shù)傳遞到另一個(gè)函數(shù)里,在那個(gè)函數(shù)執(zhí)行完后再執(zhí)行

* 如何使用事件監(jiān)聽(tīng),用onclick和addEvenListener方法

事件監(jiān)聽(tīng)的函數(shù)有on,bind,listen,addEventListener,observe

## 37. 你接觸到的js緩存方案有哪些?分別描述優(yōu)點(diǎn)及缺點(diǎn)?

* 利用storage來(lái)對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)(sessionStorage、localStorage)

* * sessionStorage:臨時(shí)的會(huì)話(huà)存儲(chǔ),只要當(dāng)前的會(huì)話(huà)窗口未關(guān)閉,存儲(chǔ)的信息就不會(huì)丟失,即便刷新了頁(yè)面或者在編輯器中更改了代碼,存儲(chǔ)的會(huì)話(huà)信息也不會(huì)丟失。

* localStorage:是一種如果你不主動(dòng)去清除,會(huì)一直將數(shù)據(jù)存儲(chǔ)在客戶(hù)端的儲(chǔ)存方式,即使關(guān)閉了瀏覽器,下次打開(kāi)的時(shí)候仍然可以看到之前存儲(chǔ)的未主動(dòng)清除的數(shù)據(jù)(即便是

殺毒軟件或者瀏覽器自帶的清除功能,也不能將localStorage存儲(chǔ)的數(shù)據(jù)清除掉).

* cookie屬于較老且最常見(jiàn)用的最多的技術(shù)了

cookie兼容所有的瀏覽器,但存儲(chǔ)的數(shù)據(jù)是有大小限制,一般是4kb;

本地存儲(chǔ)的數(shù)據(jù)會(huì)被發(fā)送到服務(wù)器

## 38. 什么是Promise? 談?wù)刟sync和await?

* (總結(jié)) promise是一個(gè)對(duì)象,主要用于異步計(jì)算,可以解決函數(shù)回調(diào)地獄,

* promise有三個(gè)狀態(tài):

* * pending[待定]初始狀態(tài)

* fulfilled[實(shí)現(xiàn)]操作成功

* rejected[被否決]操作失敗

{ 回調(diào)地獄 : 一個(gè)接口的參數(shù)會(huì)需要使用另一個(gè)接口獲取。正常的前端會(huì)把接口寫(xiě)在另一個(gè)接口的回調(diào)里。是這樣不錯(cuò),但是它增加了函數(shù)的嵌套深度也會(huì)造成一定的邏輯混亂 如果需要的是另外好幾個(gè)接口的返回?cái)?shù)據(jù)呢?這時(shí)候就會(huì)比較蛋疼了。這就是回調(diào)地獄!}

* await后面接一個(gè)會(huì)return new promise的函數(shù)并執(zhí)行它.只能放在async函數(shù)里.能使我們的異步代碼更像同步的代碼

## 39. 在瀏覽器輸入一個(gè)url地址,瀏覽器都干了什么?

域名解析 --> 發(fā)起3次握手 --> 建立連接后發(fā)起http請(qǐng)求 --> 服務(wù)器響應(yīng)請(qǐng)求,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,并請(qǐng)求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對(duì)頁(yè)面進(jìn)行渲染呈現(xiàn)給用戶(hù)

1. 瀏覽器向DNS服務(wù)器查找輸入U(xiǎn)RL對(duì)應(yīng)的IP地址。

2. DNS服務(wù)器返回網(wǎng)站的IP地址。

3. 瀏覽器根據(jù)IP地址與目標(biāo)web服務(wù)器在80端口上建立TCP連接

4. 瀏覽器獲取請(qǐng)求頁(yè)面的html代碼。

5. 瀏覽器在顯示窗口內(nèi)渲染HTML。

6. 窗口關(guān)閉時(shí),瀏覽器終止與服務(wù)器的連接。

7. 瀏覽器將該html文本顯示內(nèi)容

## 40. 開(kāi)發(fā)中常用的幾種 Content-Type ?

(1)application/x-www-form-urlencoded瀏覽器的原生 form 表單,如果不設(shè)置 enctype 屬性,那么最終就會(huì)以 application/x-www-form-urlencoded 方式提交數(shù)據(jù)。該種方式提交的數(shù)據(jù)放在 body 里面,數(shù)據(jù)按照 key1=val1&key2=val2 的方式進(jìn)行編碼,key 和 val 都進(jìn)行了 URL轉(zhuǎn)碼。

(2)multipart/form-data該種方式也是一個(gè)常見(jiàn)的 POST 提交方式,通常表單上傳文件時(shí)使用該種方式。

(3)application/json告訴服務(wù)器消息主體是序列化后的 JSON 字符串。

(4)text/xml該種方式主要用來(lái)提交 XML 格式的數(shù)據(jù)。

## 41. js中的模塊規(guī)范

前端模塊規(guī)范共有三種:

* CommonJS(同步)

* AMD CMD這兩個(gè)均是異步用在瀏覽器環(huán)境

* * AMD 提前執(zhí)行

* CMD延遲執(zhí)行

* CommonJS 用在服務(wù)器端 輸出模塊變量的最好方法是使用module.exports對(duì)象。

## 42. 遞歸實(shí)現(xiàn)深拷貝

```javascript

var obj={ //原數(shù)據(jù),包含字符串、對(duì)象、函數(shù)、數(shù)組等不同的類(lèi)型

name: "test",

main: {

a: 1,

b: 2

},

fn: function () {

},

friends: [1, 2, 3, [22, 33]]

}

function deep_copy (obj) {

let new_obj=null;

if (typeof (obj)==='object'&&obj!==null) {

new_obj=obj instanceof Array? []:{};

for (const i in obj) {

new_obj[i]=deep_copy(obj[i]);

}

} else {

new_obj=obj;

}

return new_obj

}

let obj1=deep_copy(obj)

obj.name='666'

obj.main.a=10086

console.log(obj, obj1);

```

## 43. 密封對(duì)象

* ```javascript

Object.seal()

密封對(duì)象不可擴(kuò)展,而且已有的屬性成員[[configurable]]特性將被設(shè)置成false

可以用 Object.isSealed() 來(lái)判斷對(duì)象是否已經(jīng)被密封

```

## 44. 凍結(jié)對(duì)象

* ```

Object.freeze()

凍結(jié)的對(duì)象既不可以擴(kuò)展,又是密封的,而且對(duì)象數(shù)據(jù)屬性的[[writable]]特性會(huì)被設(shè)置為false。

```

## 44. **不可擴(kuò)展對(duì)象**

* ```

Object.preventExtensions()

僅阻止添加自身的屬性。但屬性仍然可以添加到對(duì)象原型。

可以用 Object.isExtensible(obj) 來(lái)判斷對(duì)象是否可擴(kuò)展

```

## 45. for in 跟 for of 的區(qū)別

for...in 循環(huán)主要是為了遍歷對(duì)象而生,不適用于遍歷數(shù)組

for...in 循環(huán)不僅遍歷數(shù)字鍵名,還會(huì)遍歷手動(dòng)添加的其它鍵,甚至包括原型鏈上的鍵。for...of 則不會(huì)這樣

for...of 循環(huán)可以用來(lái)遍歷數(shù)組、類(lèi)數(shù)組對(duì)象,字符串、Set、Map 以及 Generator 對(duì)象

for...of 循環(huán)可以與break、continue 和 return 配合使用,跳出循環(huán)

for...of 不能循環(huán)沒(méi)有迭代器的對(duì)象

## 46. 狀態(tài)碼

常見(jiàn)的狀態(tài)碼:

200 - 請(qǐng)求成功

301 - 資源(網(wǎng)頁(yè)等)被永久轉(zhuǎn)移到其URL

404 - 請(qǐng)求的資源(網(wǎng)頁(yè))不存在

500 - 內(nèi)部服務(wù)器錯(cuò)誤

> 1開(kāi)頭的

100 繼續(xù)。客戶(hù)端繼續(xù)請(qǐng)求

101 切換協(xié)議。服務(wù)器根據(jù)客戶(hù)端的請(qǐng)求切換協(xié)議。只能切換到更高級(jí)的協(xié)議

> 2開(kāi)頭的

200 請(qǐng)求成功

201 一創(chuàng)建。成功請(qǐng)求并創(chuàng)建了新的資源

202 已接收。已經(jīng)接受請(qǐng)求,但未處理

203 請(qǐng)求成功。但返回的meta信息不在原始的服務(wù)器,而是一個(gè)副本

204 無(wú)內(nèi)容。服務(wù)器成功處理,但未返回內(nèi)容。在未更新網(wǎng)頁(yè)的情況下,可確保瀏覽器繼續(xù)顯示當(dāng)前文檔

205 重置內(nèi)容。服務(wù)器處理成功,用戶(hù)終端(例如:瀏覽器)應(yīng)重置文檔視圖??赏ㄟ^(guò)此返回碼清除瀏覽器的表單域

206 部分內(nèi)容。服務(wù)器成功處理了部分GET請(qǐng)求

> 3開(kāi)頭的

300 多種選擇。請(qǐng)求的資源可包括多個(gè)位置,相應(yīng)可返回一個(gè)資源特征與地址的列表用于用戶(hù)終端(例如:瀏覽器)選擇

301 永久移動(dòng)。請(qǐng)求的資源已被永久的移動(dòng)到新URI,返回信息會(huì)包括新的URI,瀏覽器會(huì)自動(dòng)定向到新URI。今后任何新的請(qǐng)求都應(yīng)使用新的URI代替

302 臨時(shí)移動(dòng)。與301類(lèi)似。但資源只是臨時(shí)被移動(dòng)??蛻?hù)端應(yīng)繼續(xù)使用原有URI

303 查看其它地址。與301類(lèi)似。使用GET和POST請(qǐng)求查看

304 未修改。所請(qǐng)求的資源未修改,服務(wù)器返回此狀態(tài)碼時(shí),不會(huì)返回任何資源??蛻?hù)端通常會(huì)緩存訪(fǎng)問(wèn)過(guò)的資源,通過(guò)提供一個(gè)頭信息指出客戶(hù)端希望只返回在指定日期之后修改的資源

305 使用代理。所請(qǐng)求的資源必須通過(guò)代理訪(fǎng)問(wèn)

306 已經(jīng)被廢棄的HTTP狀態(tài)碼

307 臨時(shí)重定向。與302類(lèi)似。使用GET請(qǐng)求重定向

> 4開(kāi)頭的

400 客戶(hù)端請(qǐng)求的語(yǔ)法錯(cuò)誤,服務(wù)器無(wú)法理解

401 請(qǐng)求要求用戶(hù)的身份認(rèn)證

402 保留,將來(lái)使用

403 服務(wù)器理解請(qǐng)求客戶(hù)端的請(qǐng)求,但是拒絕執(zhí)行此請(qǐng)求

404 服務(wù)器無(wú)法根據(jù)客戶(hù)端的請(qǐng)求找到資源(網(wǎng)頁(yè))。通過(guò)此代碼,網(wǎng)站設(shè)計(jì)人員可設(shè)置"您所請(qǐng)求的資源無(wú)法找到"的個(gè)性頁(yè)面

405 客戶(hù)端請(qǐng)求中的方法被禁止

406 服務(wù)器無(wú)法根據(jù)客戶(hù)端請(qǐng)求的內(nèi)容特性完成請(qǐng)求

407 請(qǐng)求要求代理的身份認(rèn)證,與401類(lèi)似,但請(qǐng)求者應(yīng)當(dāng)使用代理進(jìn)行授權(quán)

408 服務(wù)器等待客戶(hù)端發(fā)送的請(qǐng)求時(shí)間過(guò)長(zhǎng),超時(shí)

409 服務(wù)器完成客戶(hù)端的 PUT 請(qǐng)求時(shí)可能返回此代碼,服務(wù)器處理請(qǐng)求時(shí)發(fā)生了沖突

410 客戶(hù)端請(qǐng)求的資源已經(jīng)不存在。410不同于404,如果資源以前有現(xiàn)在被永久刪除了可使用410代碼,網(wǎng)站設(shè)計(jì)人員可通過(guò)301代碼指定資源的新位置

411 服務(wù)器無(wú)法處理客戶(hù)端發(fā)送的不帶Content-Length的請(qǐng)求信息

412 客戶(hù)端請(qǐng)求信息的先決條件錯(cuò)誤

413 由于請(qǐng)求的實(shí)體過(guò)大,服務(wù)器無(wú)法處理,因此拒絕請(qǐng)求。為防止客戶(hù)端的連續(xù)請(qǐng)求,服務(wù)器可能會(huì)關(guān)閉連接。如果只是服務(wù)器暫時(shí)無(wú)法處理,則會(huì)包含一個(gè)Retry-After的響應(yīng)信息

414 請(qǐng)求的URI過(guò)長(zhǎng)(URI通常為網(wǎng)址),服務(wù)器無(wú)法處理

415 服務(wù)器無(wú)法處理請(qǐng)求附帶的媒體格式

416 客戶(hù)端請(qǐng)求的范圍無(wú)效

417 服務(wù)器無(wú)法滿(mǎn)足Expect的請(qǐng)求頭信息

> 5開(kāi)頭的

500 服務(wù)器內(nèi)部錯(cuò)誤,無(wú)法完成請(qǐng)求

501 服務(wù)器不支持請(qǐng)求的功能,無(wú)法完成請(qǐng)求

502 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從遠(yuǎn)程服務(wù)器接收到了一個(gè)無(wú)效的響應(yīng)

503 由于超載或系統(tǒng)維護(hù),服務(wù)器暫時(shí)的無(wú)法處理客戶(hù)端的請(qǐng)求。延時(shí)的長(zhǎng)度可包含在服務(wù)器的Retry-After頭信息中

504 充當(dāng)網(wǎng)關(guān)或代理的服務(wù)器,未及時(shí)從遠(yuǎn)端服務(wù)器獲取請(qǐng)求

505 服務(wù)器不支持請(qǐng)求的HTTP協(xié)議的版本,無(wú)法完成處理

## 47. map跟foreach的區(qū)別

相同點(diǎn):

都是循環(huán)遍歷數(shù)組中的每一項(xiàng)

forEach和map方法里每次執(zhí)行匿名函數(shù)都支持3個(gè)參數(shù),參數(shù)分別是item(當(dāng)前每一項(xiàng))、index(索引值)、arr(原數(shù)組)

匿名函數(shù)中的this都是指向window

只能遍歷數(shù)組

區(qū)別:

map() 有返回值,可以return 出來(lái)。

forEach() 沒(méi)有返回值。

forEach() 比map()運(yùn)行更快

應(yīng)用場(chǎng)景:

# Vue

## 1. 什么是MVVM?

MVVM是model-view-viewModel的簡(jiǎn)寫(xiě), 它是一種開(kāi)發(fā)模式, 它實(shí)現(xiàn)了視圖和數(shù)據(jù)邏輯之間的分離, model模型指的是后端傳遞的數(shù)據(jù), view視圖指的是所看到的頁(yè)面, viewModel是連接視圖view和模型model的橋梁, 從而實(shí)現(xiàn)模型model到視圖view的轉(zhuǎn)化 和 視圖view到模型model的轉(zhuǎn)化, 也就是我們所說(shuō)的雙向數(shù)據(jù)綁定, 使用MVVM模式實(shí)現(xiàn)的前端框架有 vue 和 react

## 2. < keep-alive></ keep-alive>的作用是什么?

keep-alive 是 Vue 內(nèi)置的一個(gè)組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。提高渲染效率

## 3. 說(shuō)幾個(gè)vue中的指令和它的用法?

* v-model雙向數(shù)據(jù)綁定; (v-model不過(guò)是一個(gè)父子組件通信的語(yǔ)法糖,真正實(shí)現(xiàn)靠的是v-bind:綁定響應(yīng)式數(shù)據(jù),觸發(fā)oninput(事件在內(nèi)容綁定且失去焦點(diǎn)時(shí)觸發(fā))事件并進(jìn)行傳參)

* v-for循環(huán); (同一級(jí)別下,v-for優(yōu)先級(jí)比v-if高,如果他們放在同一級(jí)下,每次渲染都會(huì)先執(zhí)行循環(huán)在判斷條件,不管如何循環(huán)都會(huì)浪費(fèi)性能的.要解決的話(huà),把v-if放在外層,內(nèi)層進(jìn)行循環(huán))

* v-if, v-show 顯示與隱藏; {( v-if的原理是根據(jù)條件來(lái)動(dòng)態(tài)進(jìn)行增刪DOM元素,比較耗費(fèi)內(nèi)存,頻繁使用顯示隱藏的話(huà)不建議使用),(v-show是根據(jù)判斷條件來(lái)動(dòng)態(tài)的進(jìn)行顯示隱藏,,通過(guò)display:nonde來(lái)實(shí)現(xiàn)的,可以多次頻繁使用 )}

* v-bind 動(dòng)態(tài)綁定屬性

* v-on事件綁定; (可以同時(shí)監(jiān)聽(tīng)多個(gè)函數(shù),它相當(dāng)于DOM原生api添加事件監(jiān)聽(tīng)者,addEventlistener)

* v-once: 只綁定一次。

## 4. vue中v-if和v-show有什么區(qū)別

* v-if的原理是根據(jù)判斷條件來(lái)動(dòng)態(tài)的進(jìn)行增刪DOM元素, 比較耗費(fèi)性能和內(nèi)存, 頻繁顯示隱藏不建議使用

* v-show是根據(jù)判斷條件來(lái)動(dòng)態(tài)的進(jìn)行顯示和隱藏元素, 通過(guò)設(shè)置樣式display為block和none來(lái)實(shí)現(xiàn), 適用于頻繁顯示隱藏的情況

## 5. vue循環(huán)中為什么使用key?

需要使用key來(lái)給循環(huán)中每個(gè)節(jié)點(diǎn)做一個(gè)唯一標(biāo)識(shí),要保證一個(gè)循環(huán)中key的值各不相同, 以避免vue中的重用機(jī)制造成可能的渲染異常. 從底層來(lái)看, key屬性主要為了Diff算法就可以正確的識(shí)別此節(jié)點(diǎn)。并高效的更新虛擬DOM。

## 6. vue 中 key 值的作用?

vue 中 key 值的作用可以分為兩種情況來(lái)考慮。

第一種情況是 v-if 中使用 key。由于 Vue 會(huì)盡可能高效地渲染元素,通常會(huì)復(fù)用已有元素而不是從頭開(kāi)始渲染。因此當(dāng)我們使用 v-if 來(lái)實(shí)現(xiàn)元素切換的時(shí)候,如果切換前后含有相同類(lèi)型的元素,那么這個(gè)元素就會(huì)被復(fù)用。如果是相同的 input 元素,那么切換前后用戶(hù)的輸入不會(huì)被清除掉,這樣是不符合需求的。因此我們可以通過(guò)使用 key 來(lái)唯一的標(biāo)識(shí)一個(gè)元素,這個(gè)情況下,使用 key 的元素不會(huì)被復(fù)用。這個(gè)時(shí)候 key 的作用是用來(lái)標(biāo)識(shí)一個(gè)獨(dú)立的元素。

第二種情況是 v-for 中使用 key。用 v-for 更新已渲染過(guò)的元素列表時(shí),它默認(rèn)使用“就地復(fù)用”的策略。如果數(shù)據(jù)項(xiàng)的順序發(fā)生了改變,Vue 不會(huì)移動(dòng) DOM 元素來(lái)匹配數(shù)據(jù)項(xiàng)的順序,而是簡(jiǎn)單復(fù)用此處的每個(gè)元素。因此通過(guò)為每個(gè)列表項(xiàng)提供一個(gè) key 值,來(lái)以便 Vue 跟蹤元素的身份,從而高效的實(shí)現(xiàn)復(fù)用。這個(gè)時(shí)候 key 的作用是為了高效的更新渲染虛擬 DOM。

## 7. computed 和 watch 的差異?

(1)computed 是計(jì)算一個(gè)新的屬性,并將該屬性?huà)燧d到 Vue 實(shí)例上,而 watch 是監(jiān)聽(tīng)已經(jīng)存在且已掛載到 Vue 實(shí)例上的數(shù)據(jù),所以用 watch 同樣可以監(jiān)聽(tīng) computed 計(jì)算屬性的變化。

(2)computed 本質(zhì)是一個(gè)惰性求值的觀察者,具有緩存性,只有當(dāng)依賴(lài)變化后,第一次訪(fǎng)問(wèn) computed 屬性,才會(huì)計(jì)算新的值。而 watch 則是當(dāng)數(shù)據(jù)發(fā)生變化便會(huì)調(diào)用執(zhí)行函數(shù)。

(3)watch 支持異步操作

(4)從使用場(chǎng)景上說(shuō),

computed 適用一個(gè)數(shù)據(jù)被多個(gè)數(shù)據(jù)影響, 例子: 購(gòu)物車(chē)商品結(jié)算的時(shí)候

watch 適用一個(gè)數(shù)據(jù)影響多個(gè)數(shù)據(jù)。 例子:搜索數(shù)據(jù)

## 8. vue的組件配置對(duì)象中都有哪些常用字段?分別是什么作用?

* Data 組件中的數(shù)據(jù)

* props 組建的屬性數(shù)據(jù),接收父組件的傳值

* computed 計(jì)算屬性

* components 定義或引用子組件

* methods 自定義函數(shù)

* watch 屬性監(jiān)聽(tīng)

* filters 數(shù)據(jù)過(guò)濾器

* mounted 等生命周期函數(shù)

## 9. 監(jiān)聽(tīng)器,方法,計(jì)算屬性的區(qū)別?如何進(jìn)入深度監(jiān)聽(tīng)?

* computed是基于他的依賴(lài)進(jìn)行緩存的,computed只有在他的相關(guān)依賴(lài)發(fā)生變化,方法才會(huì)執(zhí)行

* watch和computed都是以vue的依賴(lài)追蹤機(jī)制為基礎(chǔ)的.

* watch和computed各自處理的數(shù)據(jù)關(guān)系場(chǎng)景不同

* watch擅長(zhǎng)一條數(shù)據(jù)影響多條數(shù)據(jù)(如:搜索數(shù)據(jù))

* computed擅長(zhǎng)一個(gè)數(shù)據(jù)受多條數(shù)據(jù)影響(如:購(gòu)物車(chē)商品結(jié)算)

## 10. 列舉一下Vue組件生命周期函數(shù),什么時(shí)候需要在destroyed中寫(xiě)代碼?

* beforeCreate (創(chuàng)建前) { 在這個(gè)周期里,沒(méi)有data選項(xiàng),實(shí)例沒(méi)有掛載 }

* created (創(chuàng)建完成后) { vue實(shí)例已經(jīng)創(chuàng)建,仍然不能獲取DOM元素。}

* beforeMount (掛在之前) { 虛擬DOM已經(jīng)被創(chuàng)建了 }

* mounted (掛在完成后) { 初始化頁(yè)面完成后再對(duì)數(shù)據(jù)和DOM做一些操作,需要操作DOM的方法可以放在這里 }

* beforeUpdate (更新前)

* updated (更新后)

* beforeDestroy (實(shí)例銷(xiāo)毀之前) { 確認(rèn)停止事件的確認(rèn)框 }

* destroyed (實(shí)例銷(xiāo)毀之后) { }

* 當(dāng)前頁(yè)面有事件監(jiān)聽(tīng)器或者計(jì)時(shí)器時(shí),需要在destroyed中取消或銷(xiāo)毀

## 11. vue路由的鉤子函數(shù)有哪些?

* 全局的路由鉤子函數(shù):beforeEach、afterEach

* 單個(gè)的路由鉤子函數(shù):beforeEnter

* 組件內(nèi)的路由鉤子函數(shù):beforeRouteEnter、beforeRouteLeave、beforeRouteUpdate

## 12. 介紹以下vue組件內(nèi)的路由守衛(wèi)(即路由的生命周期/鉤子函數(shù)),有哪些參數(shù)(to,from,next)

* vue組件中的路由鉤子方法有

* * beforeRouteEnter 進(jìn)入路由前調(diào)用。這里組件還未創(chuàng)建, 不能使用this

* beforeRouteUpdate 路由更新之前被調(diào)用, 組件不會(huì)重新初始化, 可以使用this

* beforeRouteLeave 離開(kāi)路由之前被調(diào)用,可以訪(fǎng)問(wèn)里面的this屬性

* 方法中都有三個(gè)參數(shù):

* * to:即將要進(jìn)入的目標(biāo)路由對(duì)象;

* from:當(dāng)前導(dǎo)航即將要離開(kāi)的路由對(duì)象;

* next :調(diào)用該方法后,才能進(jìn)入下一個(gè)路由鉤子函數(shù)

## 13. vue中數(shù)據(jù)綁定是怎么實(shí)現(xiàn)的?雙向綁定指令v-model的本質(zhì)是什么?

* Vue組件data中的數(shù)據(jù)在組件創(chuàng)建時(shí),都會(huì)被改造為set,get類(lèi)型的屬性,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)set方法就會(huì)調(diào)用,set方法中添加了重新渲染的代碼。

* v-model相當(dāng)于 v-bind:value 加 v-on:input

## 14. vue中路由如何傳值?

* 使用url拼接字符串的形式傳值 使用$route.query接收

* 使用query對(duì)象傳值 使用$route.query接收

* 使用占位符 使用$route.params接收

* 使用命名路由params字段傳值 使用$route.params接收

## 15. vue中有哪些數(shù)據(jù)傳遞方式?

* 組件傳值: 父?jìng)髯?通過(guò)props屬性或slot插槽傳遞, 子傳父,通過(guò)$emit發(fā)射自定義事件傳遞, 非父子,通過(guò)bus總線(xiàn)傳遞

* 路由傳值: 可通過(guò)url路徑傳值和編程式導(dǎo)航對(duì)象傳值

* vuex狀態(tài)管理傳值

## 16. vuex如何使用?

* 首先在項(xiàng)目中 npm install vuex 安裝

* 新建vuex狀態(tài)管理文件,導(dǎo)入vuex并添加狀態(tài)數(shù)據(jù)

* 在組件中使用mapState()函數(shù)映射狀態(tài)數(shù)據(jù)并使用

* 在組件中使用commit()函數(shù)提交申請(qǐng)修改狀態(tài)數(shù)據(jù)

## 17. Vuex的核心概念有哪些?組件如何使用store中的數(shù)據(jù)如何改變store中的數(shù)據(jù)?

* state => 存儲(chǔ)狀態(tài)(變量)

* getters => 對(duì)數(shù)據(jù)獲取之前的再次編譯,可以理解為state的計(jì)算屬性。我們?cè)诮M件中使用 $sotre.getters.fun()

* mutations => 修改狀態(tài),并且是同步的。在組件中使用$store.commit('',params)。這個(gè)和我們組件中的自定義事件類(lèi)似。

* actions => 修改狀態(tài),異步操作。在組件中使用是$store.dispath('')

* modules => 模塊化Vuex

VueX狀態(tài)管理通過(guò)vue.use()擴(kuò)展到vue框架上使用,在實(shí)例化一個(gè)倉(cāng)庫(kù)中,state是單一狀態(tài)樹(shù)、支持響應(yīng)式、默認(rèn)保存到內(nèi)存中,無(wú)法持久化,不能直接更改,數(shù)據(jù)的變化無(wú)法準(zhǔn)確追蹤和維護(hù),在嚴(yán)格模式下會(huì)報(bào)錯(cuò);在使用時(shí)在main.js中掛載后,就會(huì)在vue對(duì)象中擴(kuò)展了一個(gè)內(nèi)置對(duì)象$store(倉(cāng)庫(kù)實(shí)例),在組件中使用雙花括號(hào)$store.state打點(diǎn)調(diào)用;在create生命周期中使用this.$store。只能通過(guò)mutations來(lái)更改倉(cāng)庫(kù)中的state(數(shù)據(jù))。 mutation是唯一一種更改數(shù)據(jù)的方法,且是同步的。

更改數(shù)據(jù)需要在倉(cāng)庫(kù)中使用mutation來(lái)更改數(shù)據(jù),在里面定義很多的處理程序handlers,來(lái)更改state中的數(shù)據(jù);處理程序(函數(shù)方法)要求:第一個(gè)參數(shù)是state,第二個(gè)參數(shù)是載荷payload(攜帶過(guò)來(lái)的數(shù)據(jù));在組件中調(diào)用處理函數(shù)時(shí),通過(guò)$store.commit(‘函數(shù)方法’)也就是把用戶(hù)的更改【提交】到倉(cāng)庫(kù),讓倉(cāng)庫(kù)【改變】對(duì)應(yīng)的數(shù)據(jù)

## 18. axios和ajax的區(qū)別:

* axios實(shí)現(xiàn)了網(wǎng)頁(yè)布局?jǐn)?shù)據(jù)刷新,實(shí)現(xiàn)了對(duì)ajax的封裝

* axios是通過(guò)promise實(shí)現(xiàn)對(duì)ajax技術(shù)的一種封裝,就像jQuery實(shí)現(xiàn)ajax封裝一樣。

* 簡(jiǎn)單來(lái)說(shuō): ajax技術(shù)實(shí)現(xiàn)了網(wǎng)頁(yè)的局部數(shù)據(jù)刷新,axios實(shí)現(xiàn)了對(duì)ajax的封裝。

## 19. vue中虛擬DOM的實(shí)現(xiàn)原理

虛擬DOM是通過(guò)js對(duì)象的結(jié)構(gòu)來(lái)記錄html標(biāo)簽節(jié)點(diǎn), 當(dāng)組件數(shù)據(jù)更新需要渲染視圖時(shí),先用diff算法計(jì)算變化前后js對(duì)象(也就是虛擬DOM樹(shù))結(jié)構(gòu)的不同, 得到最小差異, 然后針對(duì)性的更新部分真實(shí)DOM節(jié)點(diǎn), 這樣可以極大提高視圖渲染效率, 節(jié)省內(nèi)存消耗

## 20. vue組件中如何監(jiān)聽(tīng)路由?

* 在組件的watch監(jiān)聽(tīng)器中對(duì)$route這個(gè)字段進(jìn)行監(jiān)聽(tīng)

* 全局監(jiān)聽(tīng)路由在app.vue組件中,watch監(jiān)聽(tīng)$route可以監(jiān)聽(tīng)全局路由

* 也可以在全局路由守衛(wèi)beforeEach函數(shù)中操作全局路由

## 21. vue中如何實(shí)現(xiàn)父子組件間的雙向數(shù)據(jù)綁定?

* Vue中父子組件雙向綁定利用父子組件傳值原理,

* 父組件向子組件傳值, 通過(guò)給子組件定義value屬性來(lái)接收傳值

* 子組件向父組件傳值, 通過(guò)子組件$emit發(fā)射名為input的自定義事件

* 在父組件中使用子組件標(biāo)簽時(shí), 在子組件標(biāo)簽上通過(guò)v-model綁定父組件數(shù)據(jù),實(shí)現(xiàn)父子組件的雙向綁定

## 22. Vue.nextTick()方法有什么作用?

* 當(dāng)vue中動(dòng)態(tài)數(shù)據(jù)修改時(shí),會(huì)導(dǎo)致界面的更新,而界面的更新屬于異步更新, 當(dāng)打印界面數(shù)據(jù)時(shí), 異步更新尚未完成, 所以打印結(jié)果是更新之前的數(shù)據(jù)

* Vue.nextTick表示異步更新函數(shù), 其參數(shù)是更新完成的回調(diào)函數(shù)

## 23. 簡(jiǎn)述vue響應(yīng)式原理?(v-model指令的原理?)

創(chuàng)建vue實(shí)例時(shí),vue會(huì)遍歷data選項(xiàng)的屬性,用object defineProperty將他們轉(zhuǎn)為getter/setter,并且在內(nèi)部追蹤相關(guān)依賴(lài),在屬性被訪(fǎng)問(wèn)和修改時(shí)通知變化。

每個(gè)組件實(shí)例都有相應(yīng)的 watcher 程序?qū)嵗?,它?huì)在組件渲染的過(guò)程中把屬性記錄為依賴(lài),之后當(dāng)依賴(lài)項(xiàng)的 setter 被調(diào)用時(shí),會(huì)通知 watcher 重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新

## 24. 在vue中如何獲取dom節(jié)點(diǎn)?什么是虛擬DOM?

利用js原生的獲取dom節(jié)點(diǎn)方法 在vue中引用jquery 使用res屬性獲取,在組件模板元素添加ref,在js中庸this.$refs獲取

vue將DOM抽象成一個(gè)js對(duì)象為節(jié)點(diǎn)的虛擬DOM樹(shù),以VNode節(jié)點(diǎn)模擬真是的DOM,并且可以進(jìn)行增刪改查的操作,這個(gè)就是虛擬DOM

## 25. vue常用的修飾符,并簡(jiǎn)要描述?

* v-model修飾符

* * .lazy(輸入框改變的時(shí)候,這個(gè)數(shù)據(jù)就會(huì)改變,.lazy會(huì)在光標(biāo)離開(kāi)輸入框是執(zhí)行)

* .trim(輸入框過(guò)濾首尾的空格)

* 事件修飾符

* * .stop(阻止事件冒泡,相當(dāng)于調(diào)用了event.stopPropagation()方法)

* .prevent(阻止默認(rèn)行為,相當(dāng)于調(diào)用了event.preventDefault()方法,比如表單的提交、a標(biāo)簽的跳轉(zhuǎn)就是默認(rèn)事件)

* .once(只能使用一次)

## 26. 單頁(yè)面應(yīng)用和多頁(yè)面應(yīng)用區(qū)別及優(yōu)缺點(diǎn)?

* 單頁(yè)面(首次進(jìn)入會(huì)請(qǐng)求一個(gè)html文件.刷新之后,點(diǎn)擊組件,路徑會(huì)變化,但不會(huì)有新的HTML請(qǐng)求)

* * 優(yōu)點(diǎn):頁(yè)面切換快 缺點(diǎn):首屏?xí)r間慢

* 多頁(yè)面(每次進(jìn)行跳轉(zhuǎn),都會(huì)請(qǐng)求一個(gè)新的HTML)

* * 優(yōu)點(diǎn):首屏進(jìn)入的時(shí)間快

* 缺點(diǎn):頁(yè)面切換會(huì)慢

## 27. vue的組件配置中都有哪些常用字段?都有什么用?

* data:組件中的數(shù)據(jù)

* props 組件的屬性數(shù)據(jù),接收父組件的傳值

* computd 計(jì)算屬性

* component 定義或者引用組件

* methods 自定義函數(shù)

* watch 監(jiān)聽(tīng)器

* filters 數(shù)據(jù)過(guò)濾器

* mounted等生命周期函數(shù)

## 28. vue中如何處理跨域請(qǐng)求

* 我在開(kāi)發(fā)中,我會(huì)設(shè)置代理服務(wù)器來(lái)解決跨域問(wèn)題.

* 在跟目錄下手動(dòng)創(chuàng)建comfig.js文件,在devServer中配置代理服務(wù)器

* 然后在使用axios請(qǐng)求數(shù)據(jù)(直接使用代理的地址),

* 中間件代理

## 29. vue 中 mixin 和 mixins 區(qū)別?

mixin 用于全局混入,會(huì)影響到每個(gè)組件實(shí)例。

mixins 應(yīng)該是我們最常使用的擴(kuò)展組件的方式了。如果多個(gè)組件中有相同的業(yè)務(wù)邏輯,就可以將這些邏輯剝離出來(lái),通過(guò) mixins 混入代碼,比如上拉下拉加載數(shù)據(jù)這種邏輯等等。另外需要注意的是 mixins 混入的鉤子函數(shù)會(huì)先于組件內(nèi)的鉤子函數(shù)執(zhí)行,并且在遇到同名選項(xiàng)的時(shí)候也會(huì)有選擇性的進(jìn)行合并

## 30. 自定義指令

* 全局指令:

```javascript

// 注冊(cè)一個(gè)全局自定義指令 `v-focus`

Vue.directive('focus', {

// 當(dāng)被綁定的元素插入到 DOM 中時(shí)……

inserted: function (el) {

// 聚焦元素

el.focus()

}

})

```

* 局部指令:

```javascript

directives: {

focus: {

// 指令的定義

inserted: function (el) {

el.focus()

}

}

}

```

* 鉤子函數(shù)

* 一個(gè)指令定義對(duì)象可以提供如下幾個(gè)鉤子函數(shù) (均為可選):

* * `bind`:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。

* `inserted`:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (僅保證父節(jié)點(diǎn)存在,但不一定已被插入文檔中)。

* `update`:所在組件的 VNode 更新時(shí)調(diào)用,**但是可能發(fā)生在其子 VNode 更新之前**。指令的值可能發(fā)生了改變,也可能沒(méi)有。但是你可以通過(guò)比較更新前后的值來(lái)忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見(jiàn)下)。

* 鉤子函數(shù)的參數(shù)

* * `el`:指令所綁定的元素,可以用來(lái)直接操作 DOM。

* `binding`:一個(gè)對(duì)象,包含以下 property:

* * `name`:指令名,不包括 `v-` 前綴。

* `value`:指令的綁定值,例如:`v-my-directive="1 + 1"` 中,綁定值為 `2`。

* `oldValue`:指令綁定的前一個(gè)值,僅在 `update` 和 `componentUpdated` 鉤子中可用。無(wú)論值是否改變都可用。

* `expression`:字符串形式的指令表達(dá)式。例如 `v-my-directive="1 + 1"` 中,表達(dá)式為 `"1 + 1"`。

* `arg`:傳給指令的參數(shù),可選。例如 `v-my-directive:foo` 中,參數(shù)為 `"foo"`。

* `modifiers`:一個(gè)包含修飾符的對(duì)象。例如:`v-my-directive.foo.bar` 中,修飾符對(duì)象為 `{ foo: true, bar: true }`。

* `vnode`:Vue 編譯生成的虛擬節(jié)點(diǎn)。移步 [VNode API](https://cn.vuejs.org/v2/api/#VNode-接口) 來(lái)了解更多詳情。

* `oldVnode`:上一個(gè)虛擬節(jié)點(diǎn),僅在 `update` 和 `componentUpdated` 鉤子中可用。

## 31. 父子組件嵌套執(zhí)行的生命周期順序

* 加載渲染過(guò)程:

* * --> 父 beforeCreate --> 父 created --> 父 beforeMount

* --> 子 beforeCreate --> 子 created --> 子 beforeMount -> 子 mounted

* --> 父 mounted

* 子組件更新過(guò)程

* * --> 父 beforeUpdate

* --> 子 beforeUpdate --> updated

* --> 父 updated

* 父組件剛更新過(guò)程

* * --> 父 beforeUpdate --> updated

* 銷(xiāo)毀過(guò)程

* * --> 父 beforeDestroy

* --> 子 beforeDetroy --> destroyed

* --> 父 destroyed

## 32. vue的優(yōu)點(diǎn)和缺點(diǎn)

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

* 簡(jiǎn)單好用: Vue.js包含基于HTML的標(biāo)準(zhǔn)模板,可以更輕松地使用和修改現(xiàn)有應(yīng)用程序。

* 單頁(yè)面應(yīng)用, 使用單文件組件結(jié)構(gòu), 用戶(hù)體驗(yàn)好,

* 性能比較好:相比其他框架, 它占用更少的空間,并提供更好的性能。

* 基于MVVM模式, 數(shù)據(jù)驅(qū)動(dòng)視圖, 更高效

* 適應(yīng)性強(qiáng):組件化設(shè)計(jì)可以提高開(kāi)發(fā)效率,方便代碼復(fù)用, 提升整個(gè)項(xiàng)目的可維護(hù)性

缺點(diǎn):

* vue生態(tài)環(huán)境不如react和angular, 但有追趕和超越的趨勢(shì)

* vue不支持IE8

* vue封裝的比較深入,不利于seo優(yōu)化, 報(bào)錯(cuò)不明顯,

## 33. 校驗(yàn)props

接收的時(shí)候使用props寫(xiě)成對(duì)象的形式它的屬性有

```javascript

type可以是以下原生類(lèi)型

String

Number

Boolean

Function

Object

Array

Symbol

required有兩個(gè)值

true 必填

false 默認(rèn)不必填

使用default選項(xiàng)來(lái)指定當(dāng)父組件未傳入?yún)?shù)時(shí)props變量的默認(rèn)值:

validator 當(dāng)校驗(yàn)規(guī)則很復(fù)雜,默認(rèn)提供的校驗(yàn)規(guī)則無(wú)法滿(mǎn)足的時(shí)候可以使用自定義函數(shù)來(lái)校驗(yàn)。

```

# vue3相比于vue2有哪些區(qū)別?

1. vue2使用時(shí)直接導(dǎo)入vue構(gòu)造函數(shù),vue3使用時(shí)通過(guò)對(duì)象解構(gòu)方式按需導(dǎo)入

2. vue3中新增了setup函數(shù),數(shù)據(jù)的定義,更新計(jì)算,監(jiān)聽(tīng)等都在setup函數(shù)中執(zhí)行

3. setup函數(shù)中的數(shù)據(jù)都需要return導(dǎo)出才能在組件模板中調(diào)用

4. setup中this為空,可以有效避免this指向修改帶來(lái)的問(wèn)題

5. Vue中的生命周期也在setup中實(shí)現(xiàn),其中取消了beforeCreata和created,其他的生命周期函數(shù)名有更新,如destoryed改成了onUnmounted

6. Vue3中使用ref函數(shù)定義值類(lèi)型數(shù)據(jù),使用reactive函數(shù)定義引用類(lèi)型數(shù)據(jù)

7. Vue3中的ref, reactive,computed等功能函數(shù)都需要從vue中解構(gòu)導(dǎo)出才能使用

8. Vue3廢棄了filters過(guò)濾器,建議使用計(jì)算屬性

# vue跟React的有那些區(qū)別

相同點(diǎn):

* 都通過(guò)虛擬DOM實(shí)現(xiàn)了視圖的渲染與更新

* 都是組件化編程, 把整個(gè)項(xiàng)目分割成一個(gè)個(gè)的組件來(lái)實(shí)現(xiàn)

* 都有單向數(shù)據(jù)流的規(guī)則執(zhí)行數(shù)據(jù)流動(dòng), 父組件通過(guò)props屬性向子組件傳值

不同點(diǎn):

* vue常用html標(biāo)簽?zāi)0?使用js實(shí)現(xiàn)邏輯,視圖與邏輯分離, react使用jsx語(yǔ)法實(shí)現(xiàn)模板, html與js相結(jié)合

* vue組件中的data數(shù)據(jù)可以直接調(diào)用并更新 而react中的state數(shù)據(jù)需要使用setState()函數(shù)執(zhí)行更新

* vue屬于漸進(jìn)式前端框架,更適用于開(kāi)發(fā)小型,靈活的項(xiàng)目, react生態(tài)更豐富,更適用于開(kāi)發(fā)專(zhuān)業(yè),大型的項(xiàng)目

* vue在組件中提供了指令,過(guò)濾器,屬性監(jiān)聽(tīng)等,可以方便快捷的操作DOM

# 為什么配置代理服務(wù)器能解決跨域

跨域主要是瀏覽器行為,是客戶(hù)端行為了,瀏覽器根據(jù)策略,判斷是否是跨域。服務(wù)器端,是沒(méi)有跨域這種說(shuō)法的。而且,服務(wù)器之間的調(diào)用,大部分情況下是為了獲取接口數(shù)據(jù)的,功能復(fù)雜,但是單一,你vue設(shè)置代理,也主要是為了避免直接請(qǐng)求過(guò)去,瀏覽器認(rèn)為跨域,自己設(shè)置個(gè)代理解決而已了

# 什么情況下使用VUEX

* 如果數(shù)據(jù)還有其他組件復(fù)用,建議放在vuex

* 如果需要跨多級(jí)組件傳遞數(shù)據(jù),建議放在vuex

* 需要持久化的數(shù)據(jù)(如登錄后用戶(hù)的信息),建議放在vuex

* 跟當(dāng)前業(yè)務(wù)組件強(qiáng)相關(guān)的數(shù)據(jù),可以放在組件內(nèi)

描述vuex

VueX狀態(tài)管理通過(guò)vue.use()擴(kuò)展到vue框架上使用,在實(shí)例化一個(gè)倉(cāng)庫(kù)中,state是初始化數(shù)據(jù)、支持響應(yīng)式、默認(rèn)保存到內(nèi)存中,無(wú)法持久化,不能直接更改,數(shù)據(jù)的變化無(wú)法準(zhǔn)確追蹤和維護(hù),在嚴(yán)格模式下會(huì)報(bào)錯(cuò);在使用時(shí)在main.js中掛載后,就會(huì)在vue對(duì)象中擴(kuò)展了一個(gè)內(nèi)置對(duì)象$store(倉(cāng)庫(kù)實(shí)例),在組件中使用雙花括號(hào)$store.state打點(diǎn)調(diào)用;在create生命周期中使用this.$store。只能通過(guò)mutations來(lái)更改倉(cāng)庫(kù)中的state(數(shù)據(jù))。 mutation是唯一一種更改數(shù)據(jù)的方法,且是同步的。異步更新數(shù)據(jù)action 需要mutation來(lái)提交

更改vuex

更改數(shù)據(jù)需要在倉(cāng)庫(kù)中使用mutation來(lái)更改數(shù)據(jù),在里面定義很多的處理程序handlers,來(lái)更改state中的數(shù)據(jù);

處理程序(函數(shù)方法)要求:第一個(gè)參數(shù)是state,第二個(gè)參數(shù)是載荷payload(攜帶過(guò)來(lái)的數(shù)據(jù));

在組件中調(diào)用處理函數(shù)時(shí),通過(guò)$store.commit(‘函數(shù)方法’)

也就是把用戶(hù)的更改【提交】到倉(cāng)庫(kù),讓倉(cāng)庫(kù)【改變】對(duì)應(yīng)的數(shù)據(jù)

# React

## 1. React中有哪些生命周期函數(shù)?

16版本之前

* constructor(props) { } 組件初始化

* componentWillMount() 渲染前 (不建議使用)

* componentDidMount() 渲染后 開(kāi)啟定時(shí)器

* componentWillReceiveProps() 接收props傳值時(shí)

* shouldComponentUpdate()控制組件是否更新

* componentWillUpdate() 組件將要更新

* Render() 組件正在渲染

* componentDidUpdate() 組件已經(jīng)更新

* componentWillUnmount() 組件將要移除 移除定時(shí)器

```javascript

1. 初始化階段: 由ReactDOM.render()觸發(fā)---初次渲染

(1).constructor() =====> props用來(lái)接收外部傳遞的數(shù)據(jù)

(2).componentWillMount() =====> 組件渲染前執(zhí)行,(一般在這個(gè)鉤子中做一些初始化的事,例如:開(kāi)啟定時(shí)器、發(fā)送網(wǎng)絡(luò)請(qǐng)求、訂閱消息)

(3).render() =====> 渲染

(4).componentDidMount() =====> 常用 渲染后

2. 更新階段: 由組件內(nèi)部this.setSate()或父組件render觸發(fā)

(1).shouldComponentUpdate() =====> 返回一個(gè)布爾值,返回true,讓組件更新,返回false不讓組件更新

(2).componentWillUpdate() =====> 數(shù)據(jù)更新前執(zhí)行

(3).render() =====> 必須使用的一個(gè)

(4).componentDidUpdate() =====> 數(shù)據(jù)更新后執(zhí)行

3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)

(1).componentWillUnmount() =====> 常用 (一般在這個(gè)鉤子中做一些收尾的事,例如:關(guān)閉定時(shí)器、取消訂閱消息)

```

16版本之后

```javascript

1. 初始化階段: 由ReactDOM.render()觸發(fā)---初次渲染

(1).constructor() =====> props用來(lái)接收外部傳遞的數(shù)據(jù)

(2).getDerivedStateFromProps

(3).render()

(4).componentDidMount() =====> 常用 (一般在這個(gè)鉤子中做一些初始化的事,例如:開(kāi)啟定時(shí)器、發(fā)送網(wǎng)絡(luò)請(qǐng)求、訂閱消息)

2. 更新階段: 由組件內(nèi)部this.setSate()或父組件重新render觸發(fā)

(1).getDerivedStateFromProps

(2).shouldComponentUpdate() =====> 返回一個(gè)布爾值,返回true,讓組件更新,返回false不讓組件更新

(3).render() =====> 渲染

(4).getSnapshotBeforeUpdate

(5).componentDidUpdate() =====> 組件更新完畢

3. 卸載組件: 由ReactDOM.unmountComponentAtNode()觸發(fā)

(1).componentWillUnmount() =====> 常用 (一般在這個(gè)鉤子中做一些收尾的事,例如:關(guān)閉定時(shí)器、取消訂閱消息)

```

## 2. React組件中的state 和 props 有何區(qū)別?

* State 是一種數(shù)據(jù)結(jié)構(gòu),在組件構(gòu)造器中定義, 是可讀可寫(xiě)的, 用于組件內(nèi)部數(shù)據(jù)的初始化和更新。 state中一般只放純數(shù)據(jù)

* Props 則是組件的配置。props 由父組件傳遞給子組件,就子組件而言,props 是只讀的。組件不能改變自身的 props,但可以修改傳遞給子組件的props。props也可以傳遞回調(diào)函數(shù)

## 3. React中keys是什么,有什么作用?

* Keys是列表通過(guò)map循環(huán)時(shí)給循環(huán)標(biāo)簽添加的屬性,用于標(biāo)記每一個(gè)循環(huán)的元素

* 在循環(huán)中要保證每一個(gè)循環(huán)標(biāo)簽keys屬性值都不相同

* 在列表數(shù)據(jù)更新時(shí), 通過(guò)keys可以快速高效的區(qū)分哪些元素是新的,然后確保視圖更新的正確和高效

## 4. React組件之間通訊有哪些方式?

* 父組件向子組件傳值:父組件通過(guò)自定義屬性向子組件傳值,子組件props參數(shù)接收并處理

* 子組件向父組件傳值:父組件通過(guò)自定義屬性向子組件傳函數(shù),子組件props接收函數(shù)并調(diào)用

* 非父子組件傳值:在全局作用域下定義變量, 通過(guò)在不同組件中對(duì)全局變量的賦值與取值來(lái)實(shí)現(xiàn)組件傳值

## 5. react的優(yōu)缺點(diǎn)

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

* * 可以通過(guò)構(gòu)造函數(shù)或類(lèi)結(jié)構(gòu)描述視圖組件,

* 集成虛擬DOM(渲染性能好)

* 單向數(shù)據(jù)流(好處是更容易追蹤數(shù)據(jù)變化排查問(wèn)題)

* 一切都是component:代碼更加模塊化,重用代碼更容易,可維護(hù)性高

* 大量使用 es6 新特性

* 缺點(diǎn):

* * jsx的一個(gè)問(wèn)題是,渲染函數(shù)render()常常包含大量邏輯,最終看著更像是程序片段,而不是視覺(jué)呈現(xiàn)。后期如果發(fā)生需求更改,維護(hù)起來(lái)比較麻煩

* 功能強(qiáng)大而全面,比vue更難上手

## 6. react使用單向數(shù)據(jù)流有什么好處?

* 單向數(shù)據(jù)流是對(duì)數(shù)據(jù)傳遞的一種約束, 他保證了組件的數(shù)據(jù)傳遞結(jié)構(gòu)穩(wěn)定且不易耦合.

* 數(shù)據(jù)只能從父組件向下流動(dòng)到子組件中,反過(guò)來(lái)則不行。這樣會(huì)防止從子組件意外改變父級(jí)組件的狀態(tài) , 極大的降低了我們組件間通信的代碼耦合

* 數(shù)據(jù)流動(dòng)單一, 便于追蹤, 追查問(wèn)題比較便捷 q

## 7. 類(lèi)組件和函數(shù)式組件有何不同?

* 函數(shù)式組件通過(guò)ES5的構(gòu)造函數(shù)結(jié)構(gòu)創(chuàng)建, 一般以數(shù)據(jù)的展示為主, 功能簡(jiǎn)單, 組件中的邏輯代碼較少

* 類(lèi)組件通過(guò)ES6的類(lèi)結(jié)構(gòu)創(chuàng)建, 允許使用更多功能,如組件狀態(tài)數(shù)據(jù),生命周期鉤子, 訪(fǎng)問(wèn)redux倉(cāng)庫(kù)等

## 8. refs的作用是什么?

shouldComponentUpdate這個(gè)函數(shù)是用來(lái)判斷是否需要調(diào)用render函數(shù)重新描繪DOM, 因?yàn)镈OM的繪制非常消耗性能, 如果我能能在這個(gè)函數(shù)中寫(xiě)一些優(yōu)化算法邏輯,控制DOM繪制的頻率和次數(shù), 則能極大的提高網(wǎng)頁(yè)渲染效率, 優(yōu)化性能

## 9. react路由跳轉(zhuǎn)時(shí)如何傳遞數(shù)據(jù)?

* 路由傳值一共有4中方式:

* * 使用url添加?拼接字符串形式傳值, 目標(biāo)組件使用this.props.location.search 接收

* 使用友好url動(dòng)態(tài)傳值, 目標(biāo)組件使用this.props.match.params接收

* 使用自定義對(duì)象傳值, 路徑使用pathname, 目標(biāo)組件使用this.props.location.xxx接收

* 使用編程式導(dǎo)航跳轉(zhuǎn)路由并傳值this.props.history.push()

* 注意:使用對(duì)象傳值以及編程式導(dǎo)航傳值時(shí)如果頁(yè)面刷新,那么傳遞的值就會(huì)消失;

## 10. 什么是Redux?

Redux是一款熱門(mén)的前端開(kāi)發(fā)庫(kù), 它是javascript程序的可預(yù)測(cè)狀態(tài)容器,可用于react項(xiàng)目的狀態(tài)管理, 使用Redux開(kāi)發(fā)的應(yīng)用易于測(cè)試,可以在不同環(huán)境中運(yùn)行,并顯示相同行為.

## 11. Redux有哪三大原則?

* 唯一數(shù)據(jù)源(整個(gè)應(yīng)用的 state 狀態(tài)數(shù)據(jù)被儲(chǔ)存在一個(gè)狀態(tài)樹(shù)(對(duì)象)中,單一狀態(tài)樹(shù)更容易跟蹤數(shù)據(jù)的變化, 方便調(diào)試檢查應(yīng)用程序)

* State 狀態(tài)是只讀的, 想要更改數(shù)據(jù)必須經(jīng)過(guò)派發(fā)action事件,通過(guò)接收action參數(shù)修改

* reducer必須是純函數(shù)(一個(gè)輸入必須對(duì)應(yīng)著唯一的輸出, 返回值取決于參數(shù))

## 12. React組件之間傳遞數(shù)據(jù)有哪些方式?

* 組件傳值: 包括父?jìng)髯? 子傳父, 兄弟組件

* 路由傳值: 包括url拼接傳值, 友好url傳值和對(duì)象傳值

* Redux傳值: 把需要傳遞的數(shù)據(jù)放入狀態(tài)管理中,各組件共享

## 13. 說(shuō)一下你對(duì)高階組件的理解

高階組件: 是 React 中用于重用組件邏輯的高級(jí)技術(shù), 它本身不是react中的組件, 而是一個(gè)函數(shù), 這個(gè)函數(shù)接受一個(gè)react組件作為參數(shù),并返回一個(gè)新組件, 實(shí)現(xiàn)了對(duì)原有組件的增強(qiáng)和優(yōu)化, 可以對(duì)原有組件中的state, props和邏輯執(zhí)行增刪改操作, 一般用于代碼重用和組件增強(qiáng)優(yōu)化

## 14. 高階組件有哪些實(shí)現(xiàn)方式? 高階組件有哪些實(shí)現(xiàn)方式?

* 屬性代理。高階組件通過(guò)被包裹的React組件來(lái)操作props, 可以增強(qiáng)組件模板和props

* 反向繼承。高階組件繼承于被包裹的React組件 可以更新state

## 15. 說(shuō)說(shuō)你對(duì)Hooks組件的理解

* hooks組件即使用了hooks語(yǔ)法構(gòu)建的函數(shù)式組件

* hooks是react中的一項(xiàng)新功能, 它可以在不使用class類(lèi)的情況下實(shí)現(xiàn)state組件狀態(tài)和生命周期等功能, 通過(guò)useState函數(shù)實(shí)現(xiàn)組件狀態(tài),通過(guò)useEffect函數(shù)實(shí)現(xiàn)生命周期

* hooks語(yǔ)法是向下兼容的, 在舊版本的react項(xiàng)目中可用.

* hooks 可以很好的替代高階組件實(shí)現(xiàn)組件的抽象和復(fù)用

* hooks只能在函數(shù)式組件中使用, 不能在普通函數(shù)或class類(lèi)組件中使用, 也不建議在循環(huán)或判斷邏輯中使用

## 16. Hooks 與 React 生命周期的關(guān)系

Hooks可以模擬實(shí)現(xiàn)react組件的生命周期,通過(guò)API函數(shù)useEffect并控制其第二個(gè)參數(shù)的傳入可以模擬組件不同時(shí)期的生命周期鉤子

## 17. Hooks 與 高階組件有何區(qū)別?

它們之間最大的不同在于,高階組件僅僅是一種開(kāi)發(fā)模式,它本身是js函數(shù)結(jié)構(gòu), 而hooks是react提供的API模式,它既能更加自然的融入到react的渲染過(guò)程也更加符合react的函數(shù)編程理念。

## 18. 什么是渲染劫持?

渲染劫持指對(duì)一個(gè)組件渲染內(nèi)容的裝飾或修改, 一般通過(guò)高階組件來(lái)實(shí)現(xiàn), 把一個(gè)組件傳入高階組件, 可以對(duì)這個(gè)組件的模板進(jìn)行修改后執(zhí)行渲染, 也可以阻止組件渲染,并修改組件中的數(shù)據(jù)和邏輯

## 19. react嚴(yán)格模式有什么作用?

StrictMode嚴(yán)格模式是一個(gè)用來(lái)突出顯示應(yīng)用程序中潛在問(wèn)題的工具, 它可以識(shí)別不安全的生命周期調(diào)用, 警告過(guò)時(shí)或已棄用的API, 并檢測(cè)意外的副作用

## 20. react有狀態(tài)組件和無(wú)狀態(tài)組件有什么區(qū)別?

* 有狀態(tài)組件通過(guò)class類(lèi)結(jié)構(gòu)定義,也叫類(lèi)組件,主要用于處理業(yè)務(wù)邏輯和做數(shù)據(jù)交互

* 無(wú)狀態(tài)組件通過(guò)函數(shù)結(jié)構(gòu)定義, 也叫函數(shù)式組件, 主要用于定義模板,用于數(shù)據(jù)的展示

## 21. 函數(shù)式組件有沒(méi)有生命周期?

函數(shù)時(shí)組件默認(rèn)是沒(méi)有生命周期的,因?yàn)楹瘮?shù)式組件的主要功能是展示數(shù)據(jù), 如果需要做很多業(yè)務(wù)邏輯的情況下可以選用類(lèi)組件,使用類(lèi)組件的生命周期, 也可以使用hooks提供的useEffect函數(shù)模擬實(shí)現(xiàn)組件的生命周期

## 22. 什么是受控組件和非受控組件?

* 受控組件和非受控組件是針對(duì)表單組件處理數(shù)據(jù)時(shí)的不同概念

* 受控組件指組件的狀態(tài)數(shù)據(jù)根據(jù)用戶(hù)輸入,實(shí)時(shí)更新,顯示在視圖中, 例如input標(biāo)簽使用onChange綁定輸入事件并通過(guò)setSatate函數(shù)更新state數(shù)據(jù), 此時(shí)組件中的數(shù)據(jù)是可控的

* 非受控組件指組件狀態(tài)數(shù)據(jù)與表單標(biāo)簽沒(méi)有直接關(guān)聯(lián), 用戶(hù)輸入與視圖更新不同步, 例如input標(biāo)簽沒(méi)有綁定onChange事件或者value屬性, 而使用refs 的DOM查找操作表單數(shù)據(jù), 并用作邏輯處理, 此時(shí)組件中的數(shù)據(jù)是不可控的

* 總之一句話(huà): 受控組件就是內(nèi)部表單通過(guò)了value和onChange綁定的組件

## 23. 說(shuō)一說(shuō)你對(duì)react虛擬DOM的理解

虛擬DOM是對(duì)DOM的抽象,本質(zhì)上是JavaScript對(duì)象, 即通過(guò)js對(duì)象模擬DOM中的節(jié)點(diǎn),由于react使用jsx語(yǔ)法構(gòu)建頁(yè)面,瀏覽器無(wú)法直接運(yùn)行jsx, 所以會(huì)把jsx結(jié)構(gòu)解析成js對(duì)象結(jié)構(gòu), 然后通過(guò)js對(duì)象渲染DOM樹(shù), 當(dāng)數(shù)據(jù)更新時(shí)虛擬DOM會(huì)通過(guò)內(nèi)部的diff算法,得到節(jié)點(diǎn)的變化,從而局部更新變化的DOM節(jié)點(diǎn), 避免了不必要的DOM操作, 提高性能

## 24. 說(shuō)一下react虛擬DOM優(yōu)化性能的實(shí)現(xiàn)步驟

* 用JavaScript對(duì)象結(jié)構(gòu)表示DOM樹(shù)的結(jié)構(gòu)(虛擬DOM);然后用這個(gè)js對(duì)象構(gòu)建一個(gè)真實(shí)DOM樹(shù),插到文檔當(dāng)中

* 當(dāng)狀態(tài)變更的時(shí)候,重新構(gòu)造一棵新的虛擬DOM樹(shù)。然后通過(guò)diff算法比較新的樹(shù)和舊的樹(shù),記錄兩棵樹(shù)差異

* 把diff算法比較的差異更新到步驟1所構(gòu)建的真正的DOM樹(shù)上,視圖就更新了

## 25. react中如何監(jiān)聽(tīng)路由

* 使用react-router-dom路由模塊提供的WithRouter高階組件給根組件props中添加路由對(duì)象

* 在根組件app.js的componentDidMount鉤子函數(shù)中this.props.history,listen()監(jiān)聽(tīng)全局路由

* 注意: 不要在react頁(yè)面組件中監(jiān)聽(tīng)路由,因?yàn)轫?yè)面銷(xiāo)毀時(shí),路由監(jiān)聽(tīng)不會(huì)取消, 可能造成重復(fù)監(jiān)聽(tīng)

## 26. react中如何實(shí)現(xiàn)樣式隔離?

* React組件之間默認(rèn)沒(méi)有樣式隔離, 所有組件的樣式都是全局樣式,

* 我們可以給每一個(gè)組件根組件添加class值, 在設(shè)置這個(gè)組件樣式時(shí),以根組件class選擇器開(kāi)頭, 只在根標(biāo)簽中起效, 以實(shí)現(xiàn)組件的樣式隔離

## 27. redux

* redux 是 js 應(yīng)用的可預(yù)測(cè)狀態(tài)的容器。 可以理解為全局?jǐn)?shù)據(jù)狀態(tài)管理工具(狀態(tài)管理機(jī)),用來(lái)做組件通信等。

* #### 為什么使用redux

當(dāng)沒(méi)有使用`redux`時(shí)兄弟組件間傳值將很麻煩,代碼很復(fù)雜冗余。使用`redux`定義全局單一的數(shù)據(jù)`Store`,可以自定義`Store`里面存放哪些數(shù)據(jù),整個(gè)數(shù)據(jù)結(jié)構(gòu)也是自己清楚的。

* 核心概念

* * state:前端中的state就是數(shù)據(jù),就是一個(gè)對(duì)象。redux中的state是不能直接修改的,只能通過(guò)action來(lái)修改,相當(dāng)于我們?cè)趩卫卸xsetter方法。

* action:redux 將每一個(gè)更改動(dòng)作描述為一個(gè)action,要更改state中的內(nèi)容,你需要發(fā)送action。一個(gè)action是一個(gè)簡(jiǎn)單的對(duì)象,用來(lái)描述state發(fā)生了什么變更。

* dispatch:是組件發(fā)出action的唯一方法。

* store:store就是整個(gè)項(xiàng)目保存數(shù)據(jù)的地方,并且只能有一個(gè)。創(chuàng)建store就是把所有reducer給它。

* reducer:數(shù)據(jù)`state`,指示`action`都有了那么就是實(shí)現(xiàn)了。reducer就是根據(jù)action來(lái)對(duì)state進(jìn)行操作。

# 小程序

## 1. 小程序的生命周期

* onLoad:頁(yè)面加載

* onReady:頁(yè)面初次渲染完成

* onShow:頁(yè)面顯示

* onHide:頁(yè)面隱藏

* onUnload:頁(yè)面卸載

## 2. 一頁(yè)小程序頁(yè)面有哪些文件組成,分別是什么作用

* .wxml: 使用微信框架設(shè)計(jì)的一套組件構(gòu)建頁(yè)面結(jié)構(gòu)

* .wxss: 用于設(shè)置頁(yè)面樣式, 和css基本一致

* .js : 設(shè)置頁(yè)面數(shù)據(jù)與邏輯

* .json: 頁(yè)面的配置信息

## 3. 小程序中rpx和px有什么不同

* px是固定單位, 指的是物理像素, 小程序樣式不建議使用px,而建議用rpx

* rpx是相對(duì)單位, 小程序把頁(yè)面寬度統(tǒng)一設(shè)置為750rpx, 它可以根據(jù)不同屏幕寬度進(jìn)行自適應(yīng),更有利于屏幕適配

## 4. 列舉幾個(gè)小程序常用組件及用法

* view : 視圖組件,塊級(jí)元素, 用于顯示塊級(jí)視圖及包裹子視圖

* text: 文本組件, 用于文字的渲染, 支持換行

* Image: 圖片組件, 用于渲染本地或在線(xiàn)圖片

* Button: 按鈕組件

* Input: 輸入框組件

* Picker: 選擇器組件

* Swiper: 輪播圖組件

## 5. 簡(jiǎn)述小程序開(kāi)發(fā)流程

* 首先在微信公眾平臺(tái)注冊(cè)小程序賬號(hào), 獲取appID

* 填寫(xiě)小程序基本信息,并下載微信開(kāi)發(fā)者工具

* 使用小程序appID創(chuàng)建小程序項(xiàng)目,并編寫(xiě)完善項(xiàng)目

* 上傳小程序項(xiàng)目為測(cè)試版, 由測(cè)試人員測(cè)試并修改BUG

* 測(cè)試完成后,在微信公眾平臺(tái)提交發(fā)布, 人工審核通過(guò)即可

## 6. 小程序中有哪些事件

* tap, touchstart, touchmove, touchend, touchcancel,

* Input, change, blue, focus, confirm

## 7. 簡(jiǎn)述微信小程序原理

微信小程序采用 JavaScript、WXML、WXSS 三種技術(shù)進(jìn)行開(kāi)發(fā),本質(zhì)就是一個(gè)單頁(yè)面應(yīng)用,所有的頁(yè)面渲染和事件處理,都在一個(gè)頁(yè)面內(nèi)進(jìn)行,但又可以通過(guò)微信客戶(hù)端調(diào)用原生的各種接口微信的架構(gòu),是數(shù)據(jù)驅(qū)動(dòng)的架構(gòu)模式,它的 UI 和數(shù)據(jù)是分離的,所有的頁(yè)面更新,都需要通過(guò)對(duì)數(shù)據(jù)的更改來(lái)實(shí)現(xiàn)

## 8. 小程序的雙向綁定和vue哪里不一樣

* Vue雙向綁定使用v-model指令即可實(shí)現(xiàn)

* 小程序雙向綁定需要自己綁定value屬性和input事件

* 而且vue中this.data即可修改數(shù)據(jù)并更新視圖,

* 小程序中只能用this.setData()修改數(shù)據(jù)才可更新視圖

## 9. 微信小程序的優(yōu)劣勢(shì)

優(yōu)勢(shì):

* 容易上手,基礎(chǔ)組件庫(kù)比較全,基本上不需要考慮兼容問(wèn)題;

* 即用即走,不用安裝,省流量,省安裝時(shí)間,不占用桌面

* 依托微信流量,天生推廣傳播優(yōu)勢(shì)

* 開(kāi)發(fā)成本比 App 低

缺點(diǎn):

* 樣式單一,部分組件已經(jīng)是成型了的,樣式不可修改,例如:幻燈片、導(dǎo)航入口

* 相對(duì)傳統(tǒng) App 要深很多

* 限制較多,頁(yè)面大小不能超過(guò)2M。不能打開(kāi)超過(guò)5個(gè)層級(jí)的頁(yè)面

## 10. bindtap和catchtap的區(qū)別?

相同點(diǎn):首先他們都是作為點(diǎn)擊事件函數(shù),就是點(diǎn)擊時(shí)觸發(fā)。在這個(gè)作用上他們是一樣的,可以不做區(qū)分

不同點(diǎn):他們的不同點(diǎn)主要是bindtap是不會(huì)阻止冒泡事件的,catchtap是阻值冒泡的

## 11. 請(qǐng)談?wù)刉XSS和CSS的異同?

* 都是用來(lái)設(shè)置頁(yè)面樣式

* WXSS 具有 CSS 大部分的特性,也做了一些擴(kuò)充和修改;

* WXSS新增了尺寸單位,WXSS 在底層支持新的尺寸單位 rpx;

* WXSS 僅支持部分 CSS 選擇器;

* WXSS 提供全局樣式與局部樣式

## 12. 小程序和H5的不同

* 運(yùn)行環(huán)境不同(小程序在微信運(yùn)行,h5在瀏覽器運(yùn)行);

* 開(kāi)發(fā)成本不同(h5需要兼容不同的瀏覽器);

* 獲取系統(tǒng)權(quán)限不同(系統(tǒng)級(jí)權(quán)限可以和小程序無(wú)縫銜接);

* 應(yīng)用在生產(chǎn)環(huán)境的運(yùn)行流暢度(h5需不斷對(duì)項(xiàng)目?jī)?yōu)化來(lái)提高用戶(hù)體驗(yàn));

## 13. 小程序如何實(shí)現(xiàn)分享

* 只需要實(shí)現(xiàn)onShareAppMessage這個(gè)函數(shù),即可點(diǎn)擊右上角菜單分享

* 調(diào)用API wx.showShareMenu() 開(kāi)啟分享功能, 點(diǎn)擊右上角菜單分享

* 給button組件添加 open-type="share" 屬性, 即可點(diǎn)擊按鈕執(zhí)行分享

## 14. 小程序組件中有哪些生命周期函數(shù)

* created: 組件實(shí)例剛剛被創(chuàng)建時(shí)執(zhí)行

* attached: 組件實(shí)例進(jìn)入頁(yè)面節(jié)點(diǎn)樹(shù)時(shí)執(zhí)行

* ready: 組件在視圖層布局完成時(shí)執(zhí)行

* moved: 組件實(shí)例被移動(dòng)到節(jié)點(diǎn)樹(shù)另一個(gè)位置時(shí)執(zhí)行

* detached: 組件實(shí)例被從頁(yè)面節(jié)點(diǎn)樹(shù)移除時(shí)執(zhí)行

* error: 組件方法拋出錯(cuò)誤時(shí)執(zhí)行

## 15. 小程序中的傳值方式有哪些:

* 1. 頁(yè)面(父組件)向子組件傳值: 通過(guò)調(diào)用子組件的props中自定義的屬性傳值, 或者 通過(guò)slot插槽傳值

* 2. 子組件向父組件(頁(yè)面)傳值: 子組件調(diào)用triggerEvent()函數(shù)發(fā)射自定義事件, 把數(shù)據(jù)放入事件函數(shù)的參數(shù)傳遞, 在子組件標(biāo)簽bind綁定事件, 數(shù)據(jù)的參數(shù)e.detail中

* 3. 頁(yè)面(父組件)主動(dòng)讀取子組件數(shù)據(jù), 通過(guò)this.selectComponent()函數(shù)可得到子組件實(shí)例

* 4. 頁(yè)面到頁(yè)面之間傳值: 通過(guò)路由傳值, 把數(shù)據(jù)拼接到url路徑上傳遞, 在目標(biāo)頁(yè)面用onLoad參數(shù)接收

* 5. 使用全局狀態(tài)管理傳值: 在app.js中g(shù)lobalData字段定義全局?jǐn)?shù)據(jù), 可以在每一個(gè)頁(yè)面getApp()引入并讀寫(xiě)

* 6. 使用數(shù)據(jù)緩存?zhèn)髦? 在一個(gè)頁(yè)面中wx.setStorage存值, 另一個(gè)頁(yè)面wx.getStogage取值

## 16. 如何實(shí)現(xiàn)下拉刷新和觸底刷新

下拉刷新

* 頁(yè)面的下拉刷新功能默認(rèn)時(shí)關(guān)閉狀態(tài), 可以在json文件中添加字段允許下拉刷新

* "enablePullDownRefresh": true

* 然后,下拉頁(yè)面會(huì)自動(dòng)調(diào)用 onPullDownRefresh()函數(shù), 在這里請(qǐng)求新數(shù)據(jù)

* 最后,數(shù)據(jù)請(qǐng)求完成的success函數(shù)中,調(diào)用wx.stopPullDownRefresh停止下拉刷新的狀態(tài)

觸底

* 觸底功能默認(rèn)開(kāi)啟, 當(dāng)頁(yè)面滾動(dòng)到底部,會(huì)調(diào)用onReachBottom()函數(shù)

## 17. 你是怎么封裝微信小程序的數(shù)據(jù)請(qǐng)求的?

1. 將所有的接口放在統(tǒng)一的js文件中并導(dǎo)出

2. 在app.js中創(chuàng)建封裝請(qǐng)求數(shù)據(jù)的方法

3. 在子頁(yè)面中調(diào)用封裝的方法請(qǐng)求數(shù)據(jù)

## 18. 小程序中如何解決跨域問(wèn)題?

* 開(kāi)發(fā)時(shí), 可在開(kāi)發(fā)工具的設(shè)置選項(xiàng)中勾選”不校驗(yàn)合法域名”, 以忽略跨域限制

* 發(fā)布時(shí), 需在小程序后臺(tái)開(kāi)發(fā)設(shè)置添加小程序中使用的域名地址,使之合法即可

## 19. 說(shuō)一些小程序中的常用API及用法

* wx.request 發(fā)起網(wǎng)絡(luò)請(qǐng)求

* wx.navigateTo 執(zhí)行路由跳轉(zhuǎn)

* wx.showModal 展示模態(tài)框

* wx.downloadFile 下載文件

* wx.setStorage 本地存儲(chǔ)

* wx.chooseImage 從相冊(cè)選擇圖片

* wx.getUserInfo 獲取用戶(hù)信息

## 20. 小程序如何獲取用戶(hù)信息?

* 使用wx.getUserInfo() 這個(gè)API,不再?gòu)棿矮@取授權(quán),建議使用以下方式

* 在事件函數(shù)中調(diào)用wx.getUserProfile() 彈框獲取用戶(hù)授權(quán), 每次都彈窗

* 給按鈕添加open-type=”getUserInfo”屬性, 用bindgetuserinfo事件綁定函數(shù)獲取

* 使用open-data組件標(biāo)簽,添加type屬性獲取某一個(gè)用戶(hù)信息

## 21. 微信API有哪些限制讓你覺(jué)得不爽?

* 個(gè)人開(kāi)發(fā)者不能使用支付API

* 個(gè)人開(kāi)發(fā)者不能用webview組件

* 某些微信API有調(diào)用頻次限制,例如分享API

## 22. 小程序頁(yè)面跳轉(zhuǎn)navigateTo,redirectTo的區(qū)別?

* navigateTo 指的是路由跳轉(zhuǎn), 如果跳轉(zhuǎn)到二級(jí)頁(yè), 導(dǎo)航條會(huì)有返回按鈕

* redirectTo 指的是路由重定向, 不會(huì)有歷史記錄,導(dǎo)航條也就不會(huì)有返回按鈕

## 23. 小程序 綁定事件怎么傳遞參數(shù)?

在觸發(fā)事件的組件標(biāo)簽上添加data-前綴的自定義屬性,在事件函數(shù)中,通過(guò)e.currentTarget.dataset打點(diǎn)調(diào)用自定義屬性獲取參數(shù)

# 白屏問(wèn)題

* 路由懶加載

* 使用Gzip壓縮,減少文件體積,加快首屏頁(yè)面打開(kāi)速度

* 骨架屏

* loading


前端面試題2022.08.08最新,持續(xù)更新中的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
慈溪市| 固始县| 乌审旗| 翁牛特旗| 左云县| 河间市| 方正县| 久治县| 盐城市| 西青区| 龙里县| 广东省| 孙吴县| 油尖旺区| 漳州市| 七台河市| 玛多县| 石家庄市| 临桂县| 阿拉善盟| 自治县| 遂昌县| 承德市| 浏阳市| 关岭| 乐陵市| 云林县| 荆州市| 枝江市| 利津县| 井陉县| 龙州县| 汉沽区| 惠来县| 龙南县| 乡城县| 同江市| 大庆市| 民勤县| 双桥区| 禄劝|