前端面試題01

1.請(qǐng)你談一談對(duì)js運(yùn)行機(jī)制的理解。
? ? ?js就是單線程,同一個(gè)時(shí)間只能做一件事情,作為瀏覽器的腳本語言,js的主要用途是與用戶互動(dòng),以及操作DOM,這決定了它只能是單線程,否則會(huì)帶來很復(fù)雜的同步問題, 所以為避免復(fù)雜性,js從一誕生就是單線程,為了利用多核CPU的計(jì)算能力,HTML5提出了Web Worker標(biāo)準(zhǔn),允許Js腳本創(chuàng)建多個(gè)線程,但是子線程完全受主線程控制,且不得操作DOM,所以這個(gè)新標(biāo)準(zhǔn)也沒有改變js是單線程的本質(zhì)。

但是這樣CPU的利用率又不是很高,所以就出現(xiàn)了任務(wù)隊(duì)列,一種是同步任務(wù),一種是異步任務(wù)。同步任務(wù)指的是:在主線程上排隊(duì)執(zhí)行,只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù)。異步任務(wù)指的是:不進(jìn)入主線程、而進(jìn)入任務(wù)隊(duì)列的任務(wù),只有當(dāng)主線程執(zhí)行完畢,才會(huì)讓任務(wù)隊(duì)列中的異步任務(wù)執(zhí)行。

異步任務(wù)的執(zhí)行機(jī)制如下:

(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。

(2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。

(3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。

(4)主線程不斷重復(fù)上面的第三步。


3.閉包

概念:閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。

閉包的優(yōu)點(diǎn):可以重復(fù)使用變量并且不會(huì)不會(huì)造成變量污染。

閉包的缺點(diǎn):容易造成內(nèi)存泄漏,

4.繼承

①原型鏈繼承

重點(diǎn):讓新實(shí)例的原型等于父類的實(shí)例

缺點(diǎn):1)新實(shí)例無法向父類構(gòu)造函數(shù)傳參

2)繼承單一

3)所有的新實(shí)例都會(huì)共享父類實(shí)例的屬性

②借用構(gòu)造函數(shù)繼承

重點(diǎn):用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的只執(zhí)行)

特點(diǎn):1)只繼承了父類構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性

2)解決了原型鏈的缺點(diǎn)

3)在子實(shí)例中可以向父實(shí)例傳參

4)可以繼承多個(gè)構(gòu)造函數(shù)屬性(call多個(gè))

缺點(diǎn):1)只能繼承父類構(gòu)造函數(shù)的屬性

2)無法實(shí)現(xiàn)構(gòu)造函數(shù)的復(fù)用

3)每個(gè)新實(shí)例都有父類構(gòu)造函數(shù)的副本,臃腫

③ 組合繼承

重點(diǎn):結(jié)合了兩種模式的優(yōu)點(diǎn),傳參和復(fù)用

特點(diǎn):1 可以繼承父類原型上的屬性,可以傳參,可復(fù)用。

2 每個(gè)新實(shí)例引入的構(gòu)造函數(shù)屬性都是私有的

缺點(diǎn):調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會(huì)替代原型上的那個(gè)父類構(gòu)造函數(shù)

④ ES6的class和extend

5 數(shù)據(jù)類型 存儲(chǔ)位置

五種基本數(shù)據(jù)類型

undefined、null、boolean、Number、string

存儲(chǔ)位置:棧

引用數(shù)據(jù)類型(對(duì)象、數(shù)組、函數(shù))

存儲(chǔ)位置:堆

引用數(shù)據(jù)類型在棧中存儲(chǔ)量指針,該指針指向堆中該實(shí)體的起始位置,當(dāng)解釋器尋找該值時(shí),會(huì)首先檢索其在棧中的地址,取得地址后,從堆中獲得實(shí)體。

6 ES6、7、8特性

① let,const

1)let和const存在塊級(jí)作用域

2) 不存在變量提升

3)不允許重復(fù)聲明

4)聲明必須賦值否則報(bào)錯(cuò)

5)暫時(shí)性死區(qū):一個(gè)塊級(jí)作用域如果定義了局部變量,就不會(huì)使用

② 結(jié)構(gòu)賦值

③ 字符串函數(shù)的擴(kuò)展,在String.prototype添加了一些方法

1)includes() 返回布爾值,表示是否找到參數(shù)字符串

2)startsWith() 返回布爾值,表示參數(shù)字符串是否在原字符串的頭部

3)endsWith() 返回布爾值,表示參數(shù)字符串是否在原字符串的尾部

4)repeat()方法返回了一個(gè)新字符串,表示將原字符串重復(fù)n次

includes和indexOf十分相似,但是includes支持NaN等

④ 模板字符串?

⑤ 箭頭函數(shù)

箭頭函數(shù)沒有作用域,this指向外部作用域,箭頭函數(shù)是函數(shù)的簡(jiǎn)化

⑥ Array.from方法用于將類似數(shù)組的對(duì)象或可遍歷的對(duì)象轉(zhuǎn)為真正的數(shù)組

⑦ 參數(shù)默認(rèn)值

⑧ 引入了rest參數(shù)(形式為"...變量名")用于獲取函數(shù)的多余參數(shù),這樣就不需要arguments對(duì)象了,rest參數(shù)中的變量代表是一個(gè)數(shù)組,所以數(shù)組特有的方法都可用于這個(gè)變量

⑨ Symbol類型,表示獨(dú)一無二的值,它是Js的第七種數(shù)據(jù)類型

⑩ ES6提供了新的數(shù)據(jù)結(jié)構(gòu)Set,它類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值

Set

7 去重

① set 去重

let s1 = new Set([...arr1,...arr2])

②?var arr=['12','32','89','12','12','78','12','32'];

? ? // 最簡(jiǎn)單數(shù)組去重法

? ? function unique1(array){

? ? ? ? var n = []; //一個(gè)新的臨時(shí)數(shù)組

? ? ? ? for(var i = 0; i < array.length; i++){ //遍歷當(dāng)前數(shù)組

? ? ? ? ? ? if (n.indexOf(array[i]) == -1)

? ? ? ? ? ? ? ? n.push(array[i]);

? ? ? ? }

? ? ? ? return n;

? ? }

? ? arr=unique1(arr);

③?// 速度最快, 占空間最多(空間換時(shí)間)

? ? function unique2(array){

? ? ? ? var n = {}, r = [], type;

? ? ? ? for (var i = 0; i < array.length; i++) {

? ? ? ? ? ? type = typeof array[i];

? ? ? ? ? ? if (!n[array[i]]) {

? ? ? ? ? ? ? ? n[array[i]] = [type];

? ? ? ? ? ? ? ? r.push(array[i]);

? ? ? ? ? ? } else if (n[array[i]].indexOf(type) < 0) {

? ? ? ? ? ? ? ? n[array[i]].push(type);

? ? ? ? ? ? ? ? r.push(array[i]);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return r;

? ? }

④? //數(shù)組下標(biāo)判斷法

? ? function unique3(array){

? ? ? ? var n = [array[0]]; //結(jié)果數(shù)組

? ? ? ? for(var i = 1; i < array.length; i++) { //從第二項(xiàng)開始遍歷

? ? ? ? ? ? if (array.indexOf(array[i]) == i)

? ? ? ? ? ? ? ? n.push(array[i]);

? ? ? ? }

? ? ? ? return n;

? ? }

⑤?Array.from與set去重

Array.from方法可以將Set結(jié)構(gòu)轉(zhuǎn)換為數(shù)組結(jié)果,而我們知道set結(jié)果是不重復(fù)的數(shù)據(jù)集,因此能夠達(dá)到去重的目的

function unique(arr) {

? ? if (!Array.isArray(arr)) {

? ? ? ? console.log('type error!')

? ? ? ? return

? ? }

? ? return Array.from(new Set(arr))

}

⑥?set與解構(gòu)賦值去重

ES6中新增了數(shù)據(jù)類型set,set的一個(gè)最大的特點(diǎn)就是數(shù)據(jù)不重復(fù)。Set函數(shù)可以接受一個(gè)數(shù)組(或類數(shù)組對(duì)象)作為參數(shù)來初始化,利用該特性也能做到給數(shù)組去重

function unique(arr) {

? ? if (!Array.isArray(arr)) {

? ? ? ? console.log('type error!')

? ? ? ? return

? ? }

? ? return [...new Set(arr)]

}

⑦?利用對(duì)象屬性去重

function unique(arr) {

? ? if (!Array.isArray(arr)) {

? ? ? ? console.log('type error!')

? ? ? ? return

? ? }

? ? let res = [],

? ? ? ? obj = {}

? ? for (let i = 0; i < arr.length; i++) {

? ? ? ? if (!obj[arr[i]]) {

? ? ? ? ? ? res.push(arr[i])

? ? ? ? ? ? obj[arr[i]] = 1

? ? ? ? } else {

? ? ? ? ? ? obj[arr[i]]++

? ? ? ? }

? ? }

? ? return res

}

⑧?相鄰元素去重

這種方法首先調(diào)用了數(shù)組的排序方法sort(),然后根據(jù)排序后的結(jié)果進(jìn)行遍歷及相鄰元素比對(duì),如果相等則跳過改元素,直到遍歷結(jié)束

function unique(arr) {

? ? if (!Array.isArray(arr)) {

? ? ? ? console.log('type error!')

? ? ? ? return

? ? }

? ? arr = arr.sort()

? ? let res = []

? ? for (let i = 0; i < arr.length; i++) {

? ? ? ? if (arr[i] !== arr[i-1]) {

? ? ? ? ? ? res.push(arr[i])

? ? ? ? }

? ? }

? ? return res

}

8 Map和Set的區(qū)別

①?Set是類似數(shù)組的一種數(shù)據(jù)結(jié)構(gòu),不同點(diǎn)在于Set中沒有重復(fù)的值

1)數(shù)組的并集

let arr1 = [1,2,3];

let arr2 = [3,4,5];

let s1 = new Set([...arr1,...arr2]) //這樣就把重復(fù)的3去掉了

console.log([...s1]);//這就是并集的結(jié)果了復(fù)制代碼

2)數(shù)組的交集

let arr1 = [1,2,3,1];

let arr2 = [3,4,5,4];

let s1 = new Set(arr1);//先去除arr1數(shù)組自身的重復(fù)項(xiàng)

let s2 = new Set(arr2);//去除arr2數(shù)組自身的重復(fù)項(xiàng)

//先簡(jiǎn)單介結(jié)一個(gè)數(shù)組的filter方法,它是es5的方法,它的參數(shù)是一個(gè)函數(shù),如果這個(gè)函數(shù)返回的是true,

//表示把數(shù)組的這一項(xiàng)留下,如果是false的話,會(huì)把數(shù)組的這一項(xiàng)刪除掉

let arr = [...s1].filter((item)=>{

? ? return s2.has(item) //has方法看s2里有沒有item這一項(xiàng)

})

console.log(arr)//[3]

②?Map是類似Object的一種鍵值對(duì)集合,區(qū)別在于Map的鍵不僅限于是字符串,其他各種類型的值包括對(duì)象都可以成為Map的鍵

9 事件委托

指的是把原本需要綁定在子元素上的響應(yīng)事件委托給父元素,當(dāng)點(diǎn)擊子元素的時(shí)候通過冒泡觸發(fā)父元素的事件

e.target 觸發(fā)事件的元素

e.currentTarget 綁定事件的元素

10? ? ?冒泡和捕獲

① 冒泡:事件按照從最特定的事件目標(biāo)到最不特定的事件目標(biāo)(document對(duì)象)的順序觸發(fā)。

② 捕獲: 事件從最不精確的對(duì)象(document 對(duì)象)開始觸發(fā),然后到最精確(也可以在窗口級(jí)別捕獲事件,不過必須由開發(fā)人員特別指定)。

11 position的值

① absolute:絕對(duì)定位,相對(duì)于static定位以外的第一個(gè)父元素定位。

② fixed: 相對(duì)于瀏覽器窗口定位

③ relative:相對(duì)定位,相對(duì)去其自身位置定位

12 什么情況下要跨域

① 因?yàn)闉g覽器有同源策略限制,不同源會(huì)造成跨域,協(xié)議不同,域名不同,端口號(hào)不同都會(huì)造成跨域

13 跨域解決辦法

① jsonp

原理:利用了標(biāo)簽具有可跨域的特性,由服務(wù)端返回預(yù)先定義好的javascript函數(shù)的調(diào)用,并且將服務(wù)端數(shù)據(jù)以該函數(shù)的參數(shù)的形式發(fā)送過來

步驟:1)創(chuàng)建一個(gè)script標(biāo)簽

2)script的src屬性設(shè)置接口地址

3)接口參數(shù)必須帶一個(gè)自定義函數(shù)名,要不然后臺(tái)無法返回?cái)?shù)據(jù)

4)通過定義函數(shù)名去接受后臺(tái)返回的數(shù)據(jù)

只能解決get跨域請(qǐng)求

② cors跨域資源共享

原理服務(wù)器設(shè)置Access-Control-Allow-OriginHTTP響應(yīng)頭之后,瀏覽器將會(huì)允許跨域

限制:瀏覽器需要支持html5,可以支持post、put等方法兼容IE9以上

14 TCP和UDP協(xié)議的區(qū)別

① TCP是面向連接的協(xié)議,在收發(fā)數(shù)據(jù)之前,必須和對(duì)方建立可靠的連接,一個(gè)TCP連接必須要經(jīng)過三次“對(duì)話“才能建立起來

1)主機(jī)A向主機(jī)B發(fā)出連接請(qǐng)求數(shù)據(jù)包:'我想給你發(fā)數(shù)據(jù),可以嗎?' 這是第一次會(huì)話

2)主機(jī)B向主機(jī)A發(fā)送同意連接和要求同步(同步就是兩臺(tái)主機(jī)一個(gè)在發(fā)送,一個(gè)在接受,協(xié)調(diào)工作)的數(shù)據(jù)包:‘可以,你什么時(shí)候發(fā)?’,這是第二次對(duì)話

3)主機(jī)A再發(fā)出一個(gè)數(shù)據(jù)包確認(rèn)主機(jī)B的要求同步:‘我想在就發(fā),你接著把’,這是第三次對(duì)話

三次對(duì)話的目的是使數(shù)據(jù)包的發(fā)送和接受tongue,進(jìn)過三次對(duì)話之后主機(jī)A才向主機(jī)B正式發(fā)送信息

TCP三次握手過程

第一次握手:主機(jī)A通過向主機(jī)B發(fā)送一個(gè)含有與tongue序列號(hào)的標(biāo)志位的數(shù)據(jù)段給主機(jī)B,向主機(jī)B請(qǐng)求建立連接,通過這個(gè)數(shù)據(jù)段,主機(jī)A告訴主機(jī)B兩件事:我想要和你通信,你可以用哪個(gè)序列號(hào)作為起始數(shù)據(jù)來回應(yīng)我。

第二次握手:主機(jī)B收到主機(jī)A的請(qǐng)求后,用一個(gè)帶有確認(rèn)應(yīng)答(ACK)和同步序列號(hào)(SYN)標(biāo)志位的數(shù)據(jù)段響應(yīng)主機(jī)A,也告訴A兩件事情,我已經(jīng)收到你的請(qǐng)求了你可以傳輸數(shù)據(jù)了,你要用哪個(gè)序列號(hào)作為起始數(shù)據(jù)段來回應(yīng)我。

第三次握手:主機(jī)A收到收到這個(gè)數(shù)據(jù)段之后,在發(fā)送一個(gè)確認(rèn)應(yīng)答,確認(rèn)已經(jīng)收到主機(jī)B的數(shù)據(jù)段“我已經(jīng)收到回復(fù),我現(xiàn)在要開始傳輸實(shí)際數(shù)據(jù)了“這樣三次握手就完成了,主機(jī)A和主機(jī)B就可以傳輸數(shù)據(jù)了。

三次握手的特點(diǎn)

沒有應(yīng)用層的數(shù)據(jù),SYN這個(gè)標(biāo)志位只有在TCP建立連接時(shí)才會(huì)被重置為1,握手完成后SYN標(biāo)志位被重圍為0

TCP簡(jiǎn)歷連接要進(jìn)行三次握手,而斷開連接要進(jìn)行四次

第一次:當(dāng)主機(jī)A完成數(shù)據(jù)傳輸后,將控制為FIN置1,提出停止TCP連接的請(qǐng)求

第二次:當(dāng)主機(jī)B收到FIN后對(duì)其作出相應(yīng),確認(rèn)這一方向上的TCP連接將關(guān)閉,將ACK置1

第三次:由B端在提出反方向的關(guān)閉請(qǐng)求,將FIN置1

第四次:主機(jī)A對(duì)主機(jī)B的請(qǐng)求進(jìn)行確認(rèn),將ACK置1,雙方向的關(guān)閉結(jié)束

由TCP的三次握手和四次斷開可以看出,TCP使用面向連接的通信方式, 大大提高了數(shù)據(jù)通信的可靠性,使發(fā)送數(shù)據(jù)端和接收端在數(shù)據(jù)正式傳輸前就有了交互, 為數(shù)據(jù)正式傳輸打下了可靠的基礎(chǔ)。

名詞解釋

1、ACK 是TCP報(bào)頭的控制位之一,對(duì)數(shù)據(jù)進(jìn)行確認(rèn)。確認(rèn)由目的端發(fā)出, 用它來告訴發(fā)送端這個(gè)序列號(hào)之前的數(shù)據(jù)段都收到了。 比如確認(rèn)號(hào)為X,則表示前X-1個(gè)數(shù)據(jù)段都收到了,只有當(dāng)ACK=1時(shí),確認(rèn)號(hào)才有效,當(dāng)ACK=0時(shí),確認(rèn)號(hào)無效,這時(shí)會(huì)要求重傳數(shù)據(jù),保證數(shù)據(jù)的完整性。

2、SYN 同步序列號(hào),TCP建立連接時(shí)將這個(gè)位置1。

3、FIN 發(fā)送端完成發(fā)送任務(wù)位,當(dāng)TCP完成數(shù)據(jù)傳輸需要斷開時(shí),,提出斷開連接的一方將這位置1。

UDP(User Data Protocol,用戶數(shù)據(jù)報(bào)協(xié)議)

1、UDP是一個(gè)非連接的協(xié)議,傳輸數(shù)據(jù)之前源端和終端不建立連接, 當(dāng)它想傳送時(shí)就簡(jiǎn)單地去抓取來自應(yīng)用程序的數(shù)據(jù),并盡可能快地把它扔到網(wǎng)絡(luò)上。 在發(fā)送端,UDP傳送數(shù)據(jù)的速度僅僅是受應(yīng)用程序生成數(shù)據(jù)的速度、 計(jì)算機(jī)的能力和傳輸帶寬的限制; 在接收端,UDP把每個(gè)消息段放在隊(duì)列中,應(yīng)用程序每次從隊(duì)列中讀一個(gè)消息段。

2、 由于傳輸數(shù)據(jù)不建立連接,因此也就不需要維護(hù)連接狀態(tài),包括收發(fā)狀態(tài)等, 因此一臺(tái)服務(wù)機(jī)可同時(shí)向多個(gè)客戶機(jī)傳輸相同的消息。

3、UDP信息包的標(biāo)題很短,只有8個(gè)字節(jié),相對(duì)于TCP的20個(gè)字節(jié)信息包的額外開銷很小。

4、吞吐量不受擁擠控制算法的調(diào)節(jié),只受應(yīng)用軟件生成數(shù)據(jù)的速率、傳輸帶寬、 源端和終端主機(jī)性能的限制。

5、UDP使用盡最大努力交付,即不保證可靠交付, 因此主機(jī)不需要維持復(fù)雜的鏈接狀態(tài)表(這里面有許多參數(shù))。

6、UDP是面向報(bào)文的。發(fā)送方的UDP對(duì)應(yīng)用程序交下來的報(bào)文, 在添加首部后就向下交付給IP層。既不拆分,也不合并,而是保留這些報(bào)文的邊界, 因此,應(yīng)用程序需要選擇合適的報(bào)文大小。

我們經(jīng)常使用“ping”命令來測(cè)試兩臺(tái)主機(jī)之間TCP/IP通信是否正常, 其實(shí)“ping”命令的原理就是向?qū)Ψ街鳈C(jī)發(fā)送UDP數(shù)據(jù)包,然后對(duì)方主機(jī)確認(rèn)收到數(shù)據(jù)包, 如果數(shù)據(jù)包是否到達(dá)的消息及時(shí)反饋回來,那么網(wǎng)絡(luò)就是通的。

ping命令是用來探測(cè)主機(jī)到主機(jī)之間是否可通信,如果不能ping到某臺(tái)主機(jī),表明不能和這臺(tái)主機(jī)建立連接。ping命令是使用 IP 和網(wǎng)絡(luò)控制信息協(xié)議 (ICMP),因而沒有涉及到任何傳輸協(xié)議(UDP/TCP) 和應(yīng)用程序。它發(fā)送icmp回送請(qǐng)求消息給目的主機(jī)。

ICMP協(xié)議規(guī)定:目的主機(jī)必須返回ICMP回送應(yīng)答消息給源主機(jī)。如果源主機(jī)在一定時(shí)間內(nèi)收到應(yīng)答,則認(rèn)為主機(jī)可達(dá)。

區(qū)別:

1、基于連接與無連接;

2、對(duì)系統(tǒng)資源的要求(TCP較多,UDP少);

3、UDP程序結(jié)構(gòu)較簡(jiǎn)單;

4、流模式與數(shù)據(jù)報(bào)模式 ;

5、TCP保證數(shù)據(jù)正確性,UDP可能丟包;

6、TCP保證數(shù)據(jù)順序,UDP不保證。

16 談一談你對(duì)MVC和MVVM的理解

MVC是一種設(shè)計(jì)模式,全稱是Model(模型)、View(視圖)和Controller(控制)

Model(數(shù)據(jù)層):儲(chǔ)存和管理數(shù)據(jù)

View(視圖層): 展示UI、響應(yīng)用戶的交互

Controller(控制層):監(jiān)聽數(shù)據(jù)的改變、控制視圖行為和處理用戶交互

他們所有的通訊都是單向的,這三層緊密聯(lián)系,又相互獨(dú)立,每一層內(nèi)部的變化不影響其它層。每一層對(duì)外提供接口,供上一層調(diào)用,實(shí)現(xiàn) 程序的模塊化。
優(yōu)點(diǎn):① 清晰的架構(gòu)以代碼的復(fù)雜性為代價(jià),小項(xiàng)目可能反而降低開發(fā)效率

② Controller層代碼難以復(fù)用,到后面會(huì)變得臃腫

③? 運(yùn)行效率相對(duì)較低,太過復(fù)雜反而不太適合中小型項(xiàng)目

MVVM是對(duì)MVC的增強(qiáng)版

將MVC中的Controller的數(shù)據(jù)和邏輯處理部分抽離出來,放在了ViewModel中,這樣只需組好View與ViewModel的數(shù)據(jù)綁定即可,MVVM顯著特點(diǎn)就是雙向綁定,view的變化會(huì)自動(dòng)更新到Model中

(項(xiàng)目復(fù)雜程度越來越高之后,MVC中的Controller會(huì)變得越來越臃腫,難以維護(hù),所以將其中的數(shù)據(jù)和邏輯處理抽離出來的MVVM更佳)

17 webstorage和cookid的區(qū)別

① 存儲(chǔ)空間不同

1)webstorage能提供5M的存儲(chǔ)空(不同瀏覽器不同),cookie提供4k的空間

2)webstroage每個(gè)域(包括子域)都有獨(dú)立的存儲(chǔ)空間,各個(gè)存儲(chǔ)空間是完全獨(dú)立的,因此不會(huì)造成數(shù)據(jù)混淆

② 服務(wù)端交互

1)webstorage中的數(shù)據(jù)僅僅本地存儲(chǔ),不會(huì)和服務(wù)器發(fā)生任何交互

2)cookie的內(nèi)容會(huì)隨著請(qǐng)求一并發(fā)送到服務(wù)器(每請(qǐng)求一個(gè)新的頁面時(shí),cookie都會(huì)被發(fā)送過去,無形中造成帶寬的浪費(fèi))

③ 接口

1)webstorag提供了許多豐富易用的接口,擁有setItem,removeItem,getItem,clear等方法,操作數(shù)據(jù)更簡(jiǎn)單

2)cookie需要自己封裝setCookie,getCookie等

④ sessionStorage和localStorage區(qū)別

1)sessionStorage:僅在當(dāng)前瀏覽器窗口關(guān)閉前有效,localStorage:始終有效,窗口或?yàn)g覽器關(guān)閉也一直保存,因此用作持久數(shù)據(jù)

2)作用域不同:sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個(gè)頁面,localStorage在所有同源窗口都是共享的

3)webStorage支持事件監(jiān)聽機(jī)制,可以將數(shù)據(jù)更新通知發(fā)送給監(jiān)聽者

說明:cookie也是必不可少的,cookie的作用是與服務(wù)器交互,作為http規(guī)范的一部分而存在,webstorage僅僅是為了本地存儲(chǔ)護(hù)數(shù)據(jù)而生。

18 請(qǐng)你談?wù)刢ookie的弊端

① cookie數(shù)量和長(zhǎng)度的限制,每個(gè)域最多有20條cookie,每個(gè)cookie的長(zhǎng)度不能超過4KB,否則就會(huì)被截掉

② 安全性問題,如果cookie被人攔截,就可以取得多哦呦的session信息,即使加密也沒用,因?yàn)閿r截者并不需要知道cookie的意義,他只要原樣轉(zhuǎn)發(fā)cookie就可以達(dá)到目的了。

③ 有些狀態(tài)不可能保存在客戶端,例如為了防止重復(fù)提交表單,我們需要在服務(wù)器端保存一個(gè)計(jì)數(shù)器,如果我們把這個(gè)計(jì)數(shù)器保存在客戶端,那么它就起不到任何作用。

19 請(qǐng)你談一談性能優(yōu)化

① 減少 HTTP請(qǐng)求

② 使用服務(wù)器端渲染

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

④ 善于使用緩存,不重復(fù)加載相同的資源

⑤ 壓縮文件

⑥ 圖片延遲加載

⑦ 減少重繪重排

20 服務(wù)器端渲染

① 客戶端渲染過程:獲取HTML文件,根據(jù)需要下載Javascript文件,運(yùn)行文件,生成DOM,在渲染。

客戶端渲染過程:

1)訪問客戶端渲染的網(wǎng)站

2)服務(wù)器返回了一個(gè)包含引入資源語句和<div id="app"></div>的HTML文件

3)客戶端通過HTTP向服務(wù)器請(qǐng)求資源,當(dāng)必要的資源都加載完畢后,執(zhí)行new Vue()開始實(shí)例化并渲染頁面

② 服務(wù)器渲染:服務(wù)器返回HTML文件,客戶端只需要解析HTML。
服務(wù)器端渲染過程:

1)訪問服務(wù)器端渲染的網(wǎng)頁

2)服務(wù)器會(huì)查看當(dāng)前路由組件需要哪些資源文件,然后將這些文件內(nèi)容填充到HTML文件,如果有ajax請(qǐng)求,就會(huì)執(zhí)行它進(jìn)行數(shù)據(jù)預(yù)取并填充到HTML文件里,最后返回這個(gè)HTML頁面

3)當(dāng)客戶端接收到這個(gè)HTML頁面時(shí),可以馬上就開始渲染頁面,與此同時(shí)頁面也會(huì)加載資源,當(dāng)必要的資源都加載完畢后,開始執(zhí)行new Vue()開始實(shí)例化并接管頁面

優(yōu)點(diǎn):首屏渲染快,SEO好

缺點(diǎn):配置麻煩,增加了服務(wù)器的計(jì)算壓力

區(qū)別在第二步,客戶端渲染的網(wǎng)站會(huì)直接返回HTML文件,而服務(wù)器端渲染的頁面則會(huì)渲染完頁面在返回這個(gè)HTML文件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容