1. 程式人生 > >前端知識點彙集整理(上)

前端知識點彙集整理(上)

# 前端面試基礎總結 ## 1、跨域解決辦法: 1、 通過jsonp跨域 2、 document.domain + iframe跨域 3、 location.hash + iframe 4、 window.name + iframe跨域 5、 postMessage跨域 6、 跨域資源共享(CORS) 7、 nginx代理跨域 8、 nodejs中介軟體代理跨域 9、 WebSocket協議跨域 ## 2、同源策略下有幾個標籤不受限制: ## 3、JS程式碼壓縮原理: 基於Base62 encode壓縮方式 簡單來說就是將相同的單詞進行壓縮,具體為將所有單詞抽取出來作為一個詞典, 然後將原始碼中表示單詞的地方改為引用詞典的下標 ## 4、Object.create() 建立一個新物件,使用現有的物件來提供新建立的物件的__proto__。 Object.create(null)在該物件上沒有繼承 Object.prototype 原型鏈上的屬性或者方法 如:toString(), hasOwnProperty()等方法 正確的寫法:Object.create(Object.prototype); ## 5、canvas繪圖環境 通過除錯canvas物件的getContext()方法。 ## 6、進位制轉換: #### Number.toString(radix) 這個函式只能將十進位制數字轉換為任意進位制的字串形式,同樣,radix表示進位制,取值2~36。 (10).toString(2)//"1010"轉2進位制 (1000).toString(36)//"rs" 轉36進位制 #### Number.parseInt(string , radix) 這個是把字串(只能由字母和數字組成),這個只能是由低進位制轉高進位制, Number.parseInt('010',8)//8 Number.parseInt('20',2)//NaN ## 7、koa2洋蔥模型: 回撥函式的巢狀 compose函式中將`context`一路傳下去給中介軟體 將`middleware`中的下一個中介軟體`fn`作為未來`next`的返回值 我們在使用use的時候將middleware存在一個數組裡面,當攔截到請求時執行callback方法,callback中呼叫了compose, compose方法使用遞迴執行中介軟體,遍歷完成返回promise.resolve(),實際最後執行的程式碼也是promise巢狀的形式。 ## 8、Array.of和new Array: 1、Array.of(3)輸出[3];new Array(3)輸出[undefined,undefined,undefined,] ## 9、DNS在進行域名解析時 DNS在進行域名解析時使用UDP,但是在域名伺服器之間傳輸時使用的是TCP ## 10、CSS權重: !important>行內樣式>id選擇器>類選擇器>標籤選擇器>萬用字元>繼承,color可繼承則為最高 ## 11、:before和:after的使用方法: 在類選擇器後面用:before和:after連線,表示輸出在標籤前後的行內樣式, 如果加上display:block輸出在標籤上下的塊級樣式,也可用於清楚浮動 ## 12、閉包的定義: 1、函式內部的變數為私有變數,外部不能訪問,但是函式內部的函式可以訪問, 閉包就是在函式內返回一個函式,使得在全域性下可以通過函式內返回的函式訪問到函式的變數 2、函式執行形成不能被釋放的私有棧記憶體 #### 閉包的使用場景: 1、使用場景一:給物件設定私有變數並且利用特權方法去訪問私有屬性 2、封裝相關功能集 優缺點: 1.保護函式內的變數安全,加強了封裝性 2.在記憶體中維持一個變數(用的太多就變成了缺點,佔記憶體) 原因: 1.在閉包的作用域鏈中引用了html元素未釋放記憶體 2.出現了迴圈引用 ## 13、檔案傳輸 #### 1、FormData(二進位制檔案資訊 提交為檔案格式) 檔名需要通過md5加密+時間戳+hash進行處理,產生唯一的檔名,使用FormData() #### 2、base64編碼(流資訊 提交為表單格式) let file='表單id'.files[0] let file_=new FileReader() file_.readAsDataURL(file) 獲取檔案base64編碼 //file_.readAsDataBuffer(file)也可以轉換成ArryBuffer格式 file_.onload=e=>{ console.log(e.target.result)//拿到編碼 } ### 大檔案上傳 #### 1、blob切片(blob.prototype.slice) 同時傳送請求(利用http可以多個併發傳遞6~7) 都上傳之後向伺服器傳送合併請求(兩次請求) 傳輸接片檔案的時候為提交為檔案格式,傳輸合併請求時為表單格式 ### 前端靜態文字下載 純文字: down_.href = window.URL.createObjectURL(new Blob(["Hello World"])); 物件 : var obj_blob = new Blob([JSON.stringify([1, 2, 3], null, 2)]) URL.createObjectURL(obj_blob) ## 14、null 與 undefined: JavaScript 中,null 是一個可以被分配的值,設定為 null 的變數意味著其無值。 而 undefined 則代表著某個變數雖然聲明瞭但是尚未進行過任何賦值。 ## 15、Loader和Plugin的不同? #### 不同的作用 1、Loader直譯為"載入器"。Webpack將一切檔案視為模組,但是webpack原生是隻能解析js檔案, 如果想將其他檔案也打包的話,就會用到loader。 所以Loader的作用是讓webpack 擁有了載入和解析非JavaScript檔案的能力。 2、Plugin直譯為"外掛"。Plugin可以擴充套件webpack的功能,讓webpack具有更多的靈活性。 在 Webpack 執行的生命週期中會廣播出許多事件,Plugin 可以監聽這些事件, 在合適的時機通過 Webpack 提供的 API 改變輸出結果。 #### 不同的用法 1、Loader在module.rules中配置,也就是說他作為模組的解析規則而存在。 型別為陣列,每一項都是一個Object, 裡面描述了對於什麼型別的檔案(test),使用什麼載入(loader)和使用的引數(options) 2、Plugin在plugins中單獨配置。 型別為陣列,每一項是一個plugin的例項,引數都通過建構函式傳入。 ## 16、物件型別: 普通物件-Object 陣列物件-Array 正則物件-RegExp 日期物件-Date 數學函式-Math 函式物件-Function ## 17、事件冒泡(Event Bubbling) : Event Bubbling 即指某個事件不僅會觸發當前元素,還會以巢狀順序傳遞到父元素中。 直觀而言就是對於某個子元素的點選事件同樣會被父元素的點選事件處理器捕獲。 ## 18、事件流被分為3個階段: 捕獲階段,目標階段,冒泡階段 ## 19、如果存在多個事件: document.onclick=function(){}後註冊的事件會覆蓋先註冊的事件, 使用addEventListener(type,listener,useCapture)則不會, useCapture:預設為false,事件冒泡從下往上逐級列印,true時相反 ## 20、V8 中執行一段JS程式碼的整個過程: 1、生成了 AST (類物件型別) 2、將 AST 通過 V8 的直譯器(也叫Ignition)轉換為位元組碼 3、在執行位元組碼的過程中,如果發現某一部分程式碼重複出現,那麼 V8 將它記做熱點程式碼(HotSpot), 然後將這麼程式碼編譯成機器碼儲存起來,這個用來編譯的工具就是V8的編譯器,程式碼執行的時間越久,那麼執行效率會越來越高 //通過直譯器逐行解釋程式碼,省去了一次性將全部的位元組碼都轉換成機器碼大大降低了記憶體的壓力 ## 21、async函式 #### 無論async函式有無await操作, 其總是返回一個Promise。 1. 如果async函式中是return一個值, 這個值就是Promise物件中resolve的值; 2. 如果async函式中是throw一個值, 這個值就是Promise物件中reject的值 ## 22、window.location window.location.search(獲取當頁面引數"?ww=xx&ww=xx") window.location.href(獲取當前頁面地址) ## 23、require.context(): 如果遇到從一個資料夾引入很多模組的情況,可以使用require.context(), 它會遍歷資料夾中的指定檔案,然後自動匯入,使得不需要每次顯式的呼叫import匯入模組 require.context(): 可以使用 require.context() 方法來建立自己的(模組)上下文。 這個方法有 3 個引數: 要搜尋的資料夾目錄 是否還應該搜尋它的子目錄 以及一個匹配檔案的正則表示式。 require.context("./test", false, /\.test\.js$/); //(建立了)一個包含了 test 資料夾(不包含子目錄)下面的、所有檔名以 `.test.js` 結尾的、 // 能被 require 請求到的檔案的上下文。 require.context模組匯出(返回)一個(require)函式 匯出的方法有 3 個屬性: resolve, keys, id。 resolve 接受一個引數request,request為test資料夾下面匹配檔案的相對路徑 keys 返回匹配成功模組的名字組成的陣列 id 是上下文模組裡面所包含的模組 id ## 24、事件迴圈: (1)所有同步任務都在主執行緒上執行,形成一個執行棧(execution context stack)。 (2)主執行緒之外,還存在一個"任務佇列"(task queue)。只要非同步任務有了執行結果,就在"任務佇列"之中放置一個事件。 (3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。 那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。 (4)主執行緒不斷重複上面的第三步。 ## 25、Class 和建構函式的區別: 1. 不存在變數提升 2. 方法預設是不可列舉的 3. class 必須使用 new 呼叫 4. ES6可以繼承靜態方法,而建構函式不能 ## 26、MVVM模式: 1、M就是Model模型層,存的一個數據物件。 2、V就是View檢視層,所有的html節點在這一層。 3、VM就是ViewModel,它通過data屬性連線Model模型層,通過el屬性連線View檢視層。 ## 27、垃圾回收機制: 棧記憶體: 按照執行順序,也就是上下文切換之後,棧頂的空間會自動被回收 v8引擎的堆垃圾回收機制: 新生代記憶體:64 位和 32 位系統下分別為 32MB 和 16MB 新生代中的變數如果經過多次回收後依然存在,那麼就會被放入到老生代記憶體中 新生代的物件主要通過 Scavenge演算法 進行垃圾回收。 老生代的物件主要通過進行標記-清除進行垃圾回收: 首先會遍歷堆中的所有物件, 對它們做上標記,然後對於程式碼環境中使用的變數以及被強引用的變數取消標記, 剩下的就是要刪除的變量了,在隨後的清除階段對其進行空間的回收。 引發記憶體碎片的問題? 存活物件的空間不連續對後續的空間分配造成障礙,V8在清除階段結束後,把存活的物件全部往一端靠攏。(最耗時間) 為了降低全堆垃圾回收帶來的停頓時間,回收方式為增量標記(incremental marking)。 ## 28、position:sticky: position:relative 和 position:fixed 兩種定位功能於一體的特殊定位,且position:sticky元素的任意父節點的 overflow 屬性必須是 visible ## 29、CORS原理 CORS原理只需要向響應頭header中注入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的 Access-Control-Allow-Origin,則就可以跨域操作了,CORS需要瀏覽器和伺服器同時支援。IE瀏覽器不能低於IE10。 簡單請求 HEAD GET POST HTTP頭部資訊不超出幾個欄位 Content-Type欄位型別是application/x-www-form-urlencoded、multipart/form-data、text/plain 非簡單請求 請求方法是PUT或DELETE,Content-Type欄位型別是application/json ## 30、四種類型的常見 JavaScript 記憶體洩露: 1:意外的全域性變數 2:被遺忘的計時器或回撥函式 3:脫離 DOM 的引用 4:閉包 ## 31、陣列的資料儲存*: 初始化空陣列時,使用快陣列,快陣列使用連續的記憶體空間,當陣列長度達到最大時,JSArray 會進行動態的擴容, 以儲存更多的元素,相對慢陣列,效能要好得多。當陣列中 hole 太多時,會轉變成慢陣列,即以雜湊表的方式 ( key-value 的形式)儲存資料,以節省記憶體空間。 ### 兩種儲存方式 fast:是 V8 實現的一個類似於陣列的類,它表示一段連續的記憶體,可以使用索引直接定位。 新建立的空陣列預設就是快陣列。當陣列滿(陣列的長度達到陣列在記憶體中申請的記憶體容量最大值)的時候, 繼續 push 時, JSArray 會進行動態的擴容,以儲存更多的元素。 slow:以雜湊表的形式儲存在記憶體空間裡,它不需要開闢連續的儲存空間, 但需要額外維護一個雜湊表,與快陣列相比,效能相對較差。 ### 儲存方式轉換 #### fast 轉變為 slow 1、當加入的索引值 index 比當前容量 capacity 差值大於等於 1024 時 2、快陣列新容量是擴容後的容量 3 倍之多時 例:var arr = [1, 2, 3] arr[2000] = 10; 當往 arr 增加一個 2000 的索引時,arr 被轉成慢陣列。節省了大量的記憶體空間 #### slow 轉變為 fast 當慢陣列的元素可存放在快陣列中且長度在 smi 之間且僅節省了50%的空間,則會轉變為快陣列 ##### 陣列進行push操作時 申請新的長度記憶體空間 將陣列拷貝到新的陣列中 把新陣列放到當前length位置 陣列的length+1 返回 length ## 32、物件進行比較: 通過JSON.stringify()轉為字串,在進行比較,或者遞迴,或者Deep Equal模組方法 ## 33、前端登入方案: session: 1、客戶端訪問login介面,伺服器收到後校驗資訊,正確後會在伺服器端儲存一個sessionId和session的對映關係 2、伺服器端返回response,並且將sessionId以set-cookie的方式傳送到客戶端,這樣sessionId就存在了客戶端。 3、客戶端傳送非登入請求時,服務端就能通過cookie中的sessionId找到對應的session來知道這次請求是誰發的 token: 1、客戶端訪問login介面,伺服器收到後校驗資訊,正確後返回一個包含使用者資訊的token 2、客戶端拿到token後,每次請求將token加入http請求的header中 單點登入(SingleSign-On,SSO):在多個應用系統中,只需要登入一次,就可以訪問其他相互信任的應用系統。 ## 34、前端效能監控 performance memory欄位代表JavaScript對記憶體的佔用。 navigation欄位統計的是一些網頁導航相關的資料: redirectCount:重定向的數量(只讀),但是這個介面有同源策略限制,即僅能檢測同源的重定向; type 返回值應該是0,1,2 中的一個。分別對應三個列舉值: 0 : TYPE_NAVIGATE (使用者通過常規導航方式訪問頁面,比如點一個連結,或者一般的get方式) 1 : TYPE_RELOAD (使用者通過重新整理,包括JS呼叫重新整理介面等方式訪問頁面) 2 : TYPE_BACK_FORWARD (使用者通過後退按鈕訪問本頁面) 最重要的是timing欄位的統計資料,它包含了網路、解析等一系列的時間資料。 var time = performance.timing performance.getEntries() '重定向時間:' + (time.redirectEnd - time.redirectStart) / 1000 'DNS解析時間:' + (time.domainLookupEnd - time.domainLookupStart) / 1000 'TCP完成握手時間:' + (time.connectEnd - time.connectStart) / 1000 'HTTP請求響應完成時間:' + (time.responseEnd - time.requestStart) / 1000 'onload事件時間:' + (time.loadEventEnd - time.loadEventStart) / 1000 ## 35、塊級元素: #### `

~

    1. 等 ` (1)總是從新行開始 (2)高度,行高、外邊距以及內邊距都可以控制。 (3)寬度預設是容器的100% (4)可以容納內聯元素和其他塊元素。 ## 36、行內元素: #### `、、、等` (1)和相鄰行內元素在一行上。 (2)高、寬無效,但水平方向的padding和margin可以設定,垂直方向的無效。 (3)預設寬度就是它本身內容的寬度。 (4)行內元素只能容納文字或則其他行內元素。(a特殊 a裡面可以放塊級元素 ) ## 37、行內元素: #### `、、` (1)和相鄰行內元素(行內塊)在一行上,但是之間會有空白縫隙。 (2)預設寬度就是它本身內容的寬度。 (3)高度,行高、外邊距以及內邊距都可以控制。 ## 38、重繪(repaint): 當元素樣式的改變不影響佈局時,瀏覽器將使用重繪對元素進行更新,此時由於只需要UI層面的重新畫素繪製,因此 損耗較少 ## 39、迴流(reflow): 當元素的尺寸、結構或觸發某些屬性時,瀏覽器會重新渲染頁面,稱為迴流。 此時,瀏覽器需要重新經過計算,計算後還需要重新頁面佈局,因此是較重的操作。會觸發迴流的操作 ## 40、JSON.parse(): JSON.parse(JSON.stringify(c,['title'])),JSON.stringify只選取陣列內的進行格式化 ## 41、cdn cdn 也叫內容分發網路,cdn就是通過中心平臺的負載均衡、內容分發、排程等功能模組,使使用者就近獲取所需內容,降低網路擁塞, 使得提高使用者訪問響應速度和命中率。 ## 42、js中i++與++i的區別: 使用i++時,i先將自身的值賦值給變數a,然後再自增1 使用++i時,i先將自身的值自增1,再將自增後的值賦值給變數a ## 43、怪異盒子模型: 1、元素的寬度和高度指的是元素內容的寬度和高度,而在怪異的盒子模型中寬度和高度還包含了 padding 和 border。 2、行內元素在怪異盒子模型中設定高度會生效 ## 44、監聽頁面位置 event.clientX,event.clientY表示點選事件發生時候的位置 x軸:pageXOffset y軸:pageYOffset ### 懶載入: #### 第一種 獲取螢幕可視視窗高度:document.documentElement.clientHeight 獲取觀測元素相對於文件頂部的距離:element.offsetTop 獲取可視視窗距離文件頂部的距離即滾動條的距離:document.documentElement.scrollTop offsetTop - scrollTop - clientHeight <= 0(該元素出現) #### 第二種 Element.getBoundingClientRect()方法 方法返回的一組矩形的集合,就是該元素的 CSS 邊框大小,位置 function isInSight(el){ const bound = el.getBoundingClientRect(); const clientHeight = window.innerHeight; return bound.top <= clientHeight + 100; } ## 45、promise #### promise是js中的一個物件,用於生成可能在將來產生結果的值且返回一個promise物件 promise 可以有三種狀態,一旦確定就不能返回: pending:初始狀態,既不是成功也不是失敗 fulfilled:意味著操作完全成功 rejected:意味著操作失敗 #### catch和reject Promise.then的第二個引數捕捉不了‘異常捕獲’和‘冒泡錯誤’,只能由catch語句進行捕獲, 並且reject是用來丟擲異常的,catch是用來處理異常的; ## 46、javascript會阻塞dom的解析 當解析過程中遇到