2020年前端面試題

想看花開發表於2020-12-07

一、頁面渲染過程(轉自:https://blog.csdn.net/longholidays/article/details/62054097)
瀏覽器的渲染頁面時,表示網站資源已經請求成功。
渲染時,大致的流程如下:
(解析html以構建dom樹->構建render樹->佈局render樹->繪製render樹)
具體的流程如下:
1:瀏覽器會將HTML解析成一個DOM樹,DOM樹的構建過程是一個深度遍歷過程,當前節點的所有子節點都構建好後才會去構建當前節點的下一個兄弟節點,
2:將CSS解析成CSS規則樹;
3:根據DOM樹和CSS來構造render樹,渲染樹不等於DOM樹,像header和display:none;這種沒有具體內容的東西就不在渲染樹中;
4:根據render樹,瀏覽器可以計算出網頁中有哪些節點,各節點的CSS以及從屬關係,然後可以計算出每個節點在螢幕中的位置;
5:遍歷render樹進行繪製頁面中的各元素。

P.S頁面發生重拍(迴流)的話,會重新載入DOM樹,影響頁面載入速度。會導致頁面重拍的原因如下:
1:頁面初始化;
2:操作DOM時;
3:某些元素的尺寸變了;
4:CSS的屬性發生改變。

瀏覽器載入頁面資源的步驟如下(部分參考網路資料):
1.使用者輸入網址(假設是第一次訪問),瀏覽器向伺服器發出請求,伺服器返回html檔案;
2.瀏覽器開始載入html程式碼,發現<head>標籤內有一個<link>標籤引用外部CSS檔案;
3.瀏覽器又發出CSS檔案的請求,伺服器返回這個CSS檔案;
4.瀏覽器繼續載入html中<body>部分的程式碼,並且CSS檔案已經拿到手了;
5.瀏覽器在程式碼中發現一個<img>標籤引用了一張圖片,向伺服器發出請求。此時瀏覽器不會等到圖片下載完,而是繼續載入後面的程式碼;
6.伺服器返回圖片檔案,由於圖片佔用了一定面積,影響了後面段落的排布,因此瀏覽器需要回過頭來重新渲染這部分程式碼;
7.瀏覽器發現了一個包含一行Javascript程式碼的<script>標籤,直接執行該指令碼;
8.Javascript指令碼執行了這條語句,它命令瀏覽器隱藏掉程式碼中的某個<div> (style.display=”none”)。少了一個元素,瀏覽器不得不重新渲染這部分程式碼;
9.</html>表示暫時載入完成;
10.此時使用者點了一下介面中的“換膚”按鈕,Javascript讓瀏覽器換了一下<link>標籤的CSS路徑;
11.瀏覽器向伺服器請求了新的CSS檔案,重新載入頁面。然後執行渲染過程。
圖文講解(另一位):https://www.cnblogs.com/dojo-lzz/p/3983335.html

2、HTTP協議詳解(轉自:https://www.cnblogs.com/ranyonsue/p/5984001.html)
HTTP協議是Hyper Text Transfer Protocol(超文字傳輸協議)的縮寫,是用於從全球資訊網(WWW:World Wide Web )伺服器傳輸超文字到本地瀏覽器的傳送協議。
HTTP是一個基於TCP/IP通訊協議來傳遞資料(HTML 檔案, 圖片檔案, 查詢結果等)。
HTTP是一個屬於應用層的物件導向的協議,由於其簡捷、快速的方式,適用於分散式超媒體資訊系統。
主要特點
1、簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

2、靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加以標記。

3.無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。

4.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

5、支援B/S及C/S模式。

二、HTTP協議中,除了GET和POST還有什麼請求?(轉自https://blog.csdn.net/weixin_33738982/article/details/91465789)
HTTP/1.1協議中共定義了八種方法(也叫“動作”)來以不同方式操作指定的資源, 不過一般來說,Web伺服器預設的只支援Post和Get這兩種“只讀”的請求方法。
OPTIONS:
這個方法可使伺服器傳回該資源所支援的所有HTTP請求方法。用’*'來代替資源名稱,向Web伺服器傳送OPTIONS請求,可以測試伺服器功能是否正常運作。

HEAD:
與GET方法一樣,都是向伺服器發出指定資源的請求。只不過伺服器將不傳回資源的本文部分。它的好處在於,使用這個方法可以在不必傳輸全部內容的情況下,就可以獲取其中“關於該資源的資訊”(元資訊或稱後設資料)。

GET:
向指定的資源發出“顯示”請求。使用GET方法應該只用在讀取資料,而不應當被用於產生“副作用”的操作中,例如在Web Application中。其中一個原因是GET可能會被網路蜘蛛等隨意訪問。參見安全方法

POST:
向指定資源提交資料,請求伺服器進行處理(例如提交表單或者上傳檔案)。資料被包含在請求本文中。這個請求可能會建立新的資源或修改現有資源,或二者皆有。

PUT:
向指定資源位置上傳其最新內容。

DELETE:
請求伺服器刪除Request-URI所標識的資源。

TRACE:
回顯伺服器收到的請求,主要用於測試或診斷。

CONNECT:
HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。通常用於SSL加密伺服器的連結(經由非加密的HTTP代理伺服器)。

方法名稱是區分大小寫的。當某個請求所針對的資源不支援對應的請求方法的時候,伺服器應當返回狀態碼405(Method Not Allowed),當伺服器不認識或者不支援對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。

通常我們用的也都是 GET 和 POST 方法,如果要實現其他的方法,需要在伺服器做相應的配置。 但是我們應該清楚,有這些個動作的存在。 而且,其他請求方式也都可以通過這兩種方式間接的來實現。

三、資料結構:八大資料結構分類****(轉自:https://blog.csdn.net/yeyazhishang/article/details/82353846)****
資料結構是指相互之間存在著一種或多種關係的資料元素的集合和該集合中資料元素之間的關係組成 。
常用的資料結構有:陣列,棧,連結串列,佇列,樹,圖,堆,雜湊表等
1、陣列
陣列是可以再記憶體中連續儲存多個元素的結構,在記憶體中的分配也是連續的,陣列中的元素通過陣列下標進行訪問,陣列下標從0開始。

2、棧
棧是一種特殊的線性表,僅能線上性表的一端操作,棧頂允許操作,棧底不允許操作。 棧的特點是:先進後出,或者說是後進先出,從棧頂放入元素的操作叫入棧,取出元素叫出棧。

3、佇列
佇列與棧一樣,也是一種線性表,不同的是,佇列可以在一端新增元素,在另一端取出元素,也就是:先進先出。從一端放入元素的操作稱為入隊,取出元素為出隊

4、連結串列
連結串列是物理儲存單元上非連續的、非順序的儲存結構,資料元素的邏輯順序是通過連結串列的指標地址實現,每個元素包含兩個結點,一個是儲存元素的資料域 (記憶體空間),另一個是指向下一個結點地址的指標域。根據指標的指向,連結串列能形成不同的結構,例如單連結串列,雙向連結串列,迴圈連結串列等。

5、樹
樹是一種資料結構,它是由n(n>=1)個有限節點組成一個具有層次關係的集合。把它叫做 “樹” 是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
每個節點有零個或多個子節點;
沒有父節點的節點稱為根節點;
每一個非根節點有且只有一個父節點;
除了根節點外,每個子節點可以分為多個不相交的子樹;
在日常的應用中,我們討論和用的更多的是樹的其中一種結構,就是二叉樹。

6、雜湊表
雜湊表,也叫雜湊表,是根據關鍵碼和值 (key和value) 直接進行訪問的資料結構,通過key和value來對映到集合中的一個位置,這樣就可以很快找到集合中的對應元素。

7、堆
堆是一種比較特殊的資料結構,可以被看做一棵樹的陣列物件,具有以下的性質:
堆中某個節點的值總是不大於或不小於其父節點的值;
堆總是一棵完全二叉樹。

將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆、斐波那契堆等。

堆的定義如下:n個元素的序列{k1,k2,ki,…,kn}當且僅當滿足下關係時,稱之為堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4…n/2),滿足前者的表示式的成為小頂堆,滿足後者表示式的為大頂堆

8、圖
圖是由結點的有窮集合V和邊的集合E組成。其中,為了與樹形結構加以區別,在圖結構中常常將結點稱為頂點,邊是頂點的有序偶對,若兩個頂點之間存在一條邊,就表示這兩個頂點具有相鄰關係。

四、網頁上哪裡可以看到請求的所有資訊
在網頁重新整理的同時,出現密密麻麻的記錄,顯示出了傳送的請求,收到的資訊等。
在這裡插入圖片描述
五、js繼承的6種方式(轉自:https://www.cnblogs.com/ranyonsue/p/11201730.html)
想要繼承,就必須要提供個父類(繼承誰,提供繼承的屬性)
在這裡插入圖片描述
1、原型鏈繼承
在這裡插入圖片描述
重點:讓新例項的原型等於父類的例項。
特點:1、例項可繼承的屬性有:例項的建構函式的屬性,父類建構函式屬性,父類原型的屬性。(新例項不會繼承父類例項的屬性!)
缺點:1、新例項無法向父類建構函式傳參。
   2、繼承單一。
   3、所有新例項都會共享父類例項的屬性。(原型上的屬性是共享的,一個例項修改了原型屬性,另一個例項的原型屬性也會被修改!)

2、借用建構函式繼承
在這裡插入圖片描述
重點:用.call()和.apply()將父類建構函式引入子類函式(在子類函式中做了父類函式的自執行(複製))
特點:1、只繼承了父類建構函式的屬性,沒有繼承父類原型的屬性。
   2、解決了原型鏈繼承缺點1、2、3。
   3、可以繼承多個建構函式屬性(call多個)。
   4、在子例項中可向父例項傳參。
缺點:1、只能繼承父類建構函式的屬性。
       2、無法實現建構函式的複用。(每次用每次都要重新呼叫)
       3、每個新例項都有父類建構函式的副本,臃腫。

3、組合繼承(組合原型鏈繼承和借用建構函式繼承)(常用)
在這裡插入圖片描述
重點:結合了兩種模式的優點,傳參和複用
特點:1、可以繼承父類原型上的屬性,可以傳參,可複用。
   2、每個新例項引入的建構函式屬性是私有的。
缺點:呼叫了兩次父類建構函式(耗記憶體),子類的建構函式會代替原型上的那個父類建構函式。

4、原型式繼承
在這裡插入圖片描述
重點:用一個函式包裝一個物件,然後返回這個函式的呼叫,這個函式就變成了個可以隨意增添屬性的例項或物件。object.create()就是這個原理。
特點:類似於複製一個物件,用函式來包裝。
缺點:1、所有例項都會繼承原型上的屬性。
   2、無法實現複用。(新例項屬性都是後面新增的)

5、寄生式繼承
在這裡插入圖片描述
重點:就是給原型式繼承外面套了個殼子。
優點:沒有建立自定義型別,因為只是套了個殼子返回物件(這個),這個函式順理成章就成了建立的新物件。
缺點:沒用到原型,無法複用。

6、寄生組合式繼承(常用)
寄生:在函式內返回物件然後呼叫
組合:1、函式的原型等於另一個例項。2、在函式中用apply或者call引入另一個建構函式,可傳參
在這裡插入圖片描述
重點:修復了組合繼承的問題

六、JS陣列轉字串(3種方法)****(轉自:http://c.biancheng.net/view/5673.html)
JavaScript 允許陣列與字串之間相互轉換。其中 Array 方法物件定義了 3 個方法,可以把陣列轉換為字串。
1、toString():將陣列轉換成一個字串
在這裡插入圖片描述

2、toLocalString() :把陣列轉換成本地約定的字串
與 toString() 方法用法基本相同,主要區別在於 toLocalString() 方法能夠使用使用者所在地區特定的分隔符把生成的字串連線起來,形成一個字串。
在這裡插入圖片描述

join():將陣列元素連線起來以構建一個字串
把陣列轉換為字串,不過它可以指定分隔符。在呼叫 join() 方法時,可以傳遞一個引數作為分隔符來連線每個元素。如果省略引數,預設使用逗號作為分隔符,這時與 toString() 方法轉換操作效果相同。
在這裡插入圖片描述
如何把字串轉化為陣列?
split() 方法是 String 物件方法,與 join() 方法操作正好相反。該方法可以指定兩個引數,第 1 個引數為分隔符,指定從哪兒進行分隔的標記;第 2 個引數指定要返回陣列的長度。
在這裡插入圖片描述
七、javascript中call()、apply()、bind()的用法(轉自:https://www.cnblogs.com/Shd-Study/p/6560808.html)
在這裡插入圖片描述
輸出:
obj.objAge; //17
obj.myFun() //小張年齡undefined
在這裡插入圖片描述
輸出:
shows() //盲僧

第一個列印裡面的this 指向obj,第二個全域性宣告的shows()函式 this 是window ;**

call()、apply()、bind() 都是用來重定義 this 這個物件的
在這裡插入圖片描述
obj.myFun.call(db);    //德瑪年齡99
obj.myFun.apply(db);    //德瑪年齡99
obj.myFun.bind(db)();   //德瑪年齡99

以上出了bind 方法後面多了個 () 外 ,結果返回都一致!
由此得出結論,bind 返回的是一個新的函式,你必須呼叫它才會被執行

對比call 、bind 、 apply 傳參情況下
在這裡插入圖片描述
在這裡插入圖片描述
從上面四個結果不難看出:
call 、bind 、 apply 這三個函式的第一個引數都是 this 的指向物件,第二個引數差別就來了:
call 的引數是直接放進去的,第二第三第 n 個引數全都用逗號分隔,直接放到後面 obj.myFun.call(db,‘成都’, … ,‘string’ )。
apply 的所有引數都必須放在一個陣列裡面傳進去 obj.myFun.apply(db,[‘成都’, …, ‘string’ ])。
bind 除了返回是函式以外,它 的引數和 call 一樣。
當然,三者的引數不限定是 string 型別,允許是各種型別,包括函式 、 object 等等!

八、const用法(轉自:https://www.jb51.net/article/182185.htm)
const定義的變數不可以修改,而且必須初始化。
在這裡插入圖片描述
const 宣告一個只讀的常量,一旦宣告,常量的值就不能改變。
所謂的常量就是不能改變的值。
在這裡插入圖片描述
上面程式碼表明改變常量的值會報錯。
const宣告的變數不得改變值,這意味著,const一旦宣告變數,就必須立即初始化,不能留到以後賦值。
我們都知道const一般宣告一個只讀的常量,宣告之後就不能修改了,並且宣告時必須初始化
在這裡插入圖片描述
特殊情況:
在這裡插入圖片描述
可以理解為:
dog中儲存的是物件的房間號(記憶體地址)
dog.name= ‘wangcai’,在給物件新增屬性的過程,並沒有改變這個地址,所以結果正常顯示
其實const保證的並不是變數的值不動,而是變數指向的記憶體地址不得改動
在這裡插入圖片描述
● js看到變數message後,會給message分配一個空房間(記憶體空間)
看到等號右側的字串‘hello’時,會立馬給它安排另一個房間,並把‘hello’放到這個房間
● js會拿小本本抄下這個房間的房間號(記憶體地址)
● 把這個房間號放到message這個房間裡面,這時message中儲存的就是hello字串的儲存地址(即指標)
當我們再次賦值時

在這裡插入圖片描述
js會將儲存‘word’字串的地址賦給message,而message又是用const定義的變數,不可以改變變數裡儲存的記憶體地址,這時就會❌報錯
重點:const保證的並不是變數的值不動,而是變數指向的記憶體地址不得改動

九、js選擇器
一、原生JS選擇器
JS選擇器常用的有getElementById()、getElementsByName()、getElementsByTagName()、getElementsByClassName()、querySelector()、querySelectorAll()

A: getElementById(ID): 返回對指定ID的第一個物件的引用,如果在文件中查詢一個特定的元素,最有效的方法是getElementById()
B: getElementsByName(name): 返回文件中name屬性為name值的元素,因為name屬性值不是唯一的,所以查詢到的結果有可能返回的是一個陣列,而不是一個元素。
C: getElementsByTagName(tagname): 返回文件中指定標籤的元素
D: getElementsByClassName():返回文件中所有指定類名的元素
E: querySelector():返回文件中匹配指定css選擇器的第一個元素
F: querySelectorAll():返回文件中匹配指定css選擇器的第一個元素

在這裡插入圖片描述

二、jQuery選擇器#
內容
基本選擇器有ID選擇器、類選擇器、標籤選擇器、通用選擇器,事件的新增方法如下:
$(…).事件名(function() { });
屬性樣式有:
$(…).css(“border”,“1px solid red”)
$(…).css({…})
$(…).css(“border”)
$(…).attr(屬性名,值)
$(…).html() innerHTML
$(…).text() innerText
$(…).val() value值
$(…).addClass() 增加
$(…).removeClass() 移除
$(…).toggleClass() 開關**
在這裡插入圖片描述
十、Utf-8編碼漢字佔多少個位元組

一個utf8數字佔1個位元組

一個utf8英文字母佔1個位元組

少數是漢字每個佔用3個位元組,多數佔用4個位元組。

UTF-8 使用一至四個位元組為每個字元編碼。128 個 ASCII 字元(Unicode 範圍由 U+0000 至 U+007F)只需一個位元組,帶有變音符號的拉丁文、希臘文、西裡爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及馬爾地夫語(Unicode 範圍由 U+0080 至 U+07FF)需要二個位元組,其他基本多文種平面(BMP)中的字元(CJK屬於此類-Qieqie注)使用三個位元組,其他 Unicode 輔助平面的字元使用四位元組編碼。

相關文章