2019前端面試系列——JS面試題

来源:https://www.cnblogs.com/owenzh/archive/2020/07/02/13224518.html
-Advertisement-
Play Games

目錄判斷 js 類型的方式ES5 和 ES6 分別幾種方式聲明變數閉包的概念?優缺點?淺拷貝和深拷貝數組去重的方法DOM 事件有哪些階段?談談對事件代理的理解js 執行機制、事件迴圈介紹下 promise.allasync 和 awaitES6 的 class 和構造函數的區別transform、t ...


目錄

  回到頂部

判斷 js 類型的方式

1. typeof

可以判斷出'string','number','boolean','undefined','symbol'
但判斷 typeof(null) 時值為 'object'; 判斷數組和對象時值均為 'object'

2. instanceof

原理是 構造函數的 prototype 屬性是否出現在對象的原型鏈中的任何位置

複製function A() {}
let a = new A();
a instanceof A     //true,因為 Object.getPrototypeOf(a) === A.prototype;
3. Object.prototype.toString.call()

常用於判斷瀏覽器內置對象,對於所有基本的數據類型都能進行判斷,即使是 null 和 undefined

4. Array.isArray()

用於判斷是否為數組

回到頂部

ES5 和 ES6 分別幾種方式聲明變數

ES5 有倆種:varfunction
ES6 有六種:增加四種,letconstclassimport

註意:letconstclass聲明的全局變數再也不會和全局對象的屬性掛鉤

回到頂部

閉包的概念?優缺點?

閉包的概念:閉包就是能讀取其他函數內部變數的函數。

優點:

  1. 避免全局變數的污染
  2. 希望一個變數長期存儲在記憶體中(緩存變數)

缺點:

  1. 記憶體泄露(消耗)
  2. 常駐記憶體,增加記憶體使用量
回到頂部

淺拷貝和深拷貝

  • 淺拷貝
複製// 第一層為深拷貝
Object.assign()
Array.prototype.slice()
擴展運算符 ...
  • 深拷貝
複製JSON.parse(JSON.stringify())

遞歸函數

複製function cloneObject(obj) {
  var newObj = {} //如果不是引用類型,直接返回
  if (typeof obj !== 'object') {
    return obj
  }
  //如果是引用類型,遍歷屬性
  else {
    for (var attr in obj) {
      //如果某個屬性還是引用類型,遞歸調用
      newObj[attr] = cloneObject(obj[attr])
    }
  }
  return newObj
}

如何實現一個深拷貝
詳細解析賦值、淺拷貝和深拷貝的區別

回到頂部

數組去重的方法

1.ES6 的 Set
複製let arr = [1,1,2,3,4,5,5,6]
let arr2 = [...new Set(arr)]
2.reduce()
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.reduce(function(ar,cur) {
if(!ar.includes(cur)) {
ar.push(cur)
}

return ar
},[])

3.filter()
複製// 這種方法會有一個問題:[1,'1']會被當做相同元素,最終輸入[1]
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.filter(function(item,index) {
  // indexOf() 方法可返回某個指定的 字元串值 在字元串中首次出現的位置
  return arr.indexOf(item) === index
})
回到頂部

DOM 事件有哪些階段?談談對事件代理的理解

分為三大階段:捕獲階段--目標階段--冒泡階段

事件代理簡單說就是:事件不直接綁定到某元素上,而是綁定到該元素的父元素上,進行觸發事件操作時(例如'click'),再通過條件判斷,執行事件觸發後的語句(例如'alert(e.target.innerHTML)')

好處:(1)使代碼更簡潔;(2)節省記憶體開銷

回到頂部

js 執行機制、事件迴圈

      JavaScript 語言的一大特點就是單線程,同一個時間只能做一件事。單線程就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。JavaScript 語言的設計者意識到這個問題,將所有任務分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous),在所有同步任務執行完之前,任何的非同步任務是不會執行的。
      當我們打開網站時,網頁的渲染過程就是一大堆同步任務,比如頁面骨架和頁面元素的渲染。而像載入圖片音樂之類占用資源大耗時久的任務,就是非同步任務。關於這部分有嚴格的文字定義,但本文的目的是用最小的學習成本徹底弄懂執行機制,所以我們用導圖來說明:
js執行機制

導圖要表達的內容用文字來表述的話:
      同步和非同步任務分別進入不同的執行"場所",同步的進入主線程,非同步的進入 Event Table 並註冊函數。當指定的事情完成時,Event Table 會將這個函數移入 Event Queue。主線程內的任務執行完畢為空,會去 Event Queue 讀取對應的函數,進入主線程執行。上述過程會不斷重覆,也就是常說的 Event Loop(事件迴圈)。
      我們不禁要問了,那怎麼知道主線程執行棧為空啊?js 引擎存在 monitoring process 進程,會持續不斷的檢查主線程執行棧是否為空,一旦為空,就會去 Event Queue 那裡檢查是否有等待被調用的函數。換一張圖片也許更好理解主線程的執行過程:


      上圖用文字表述就是:主線程從"任務隊列"中讀取事件,這個過程是迴圈不斷的,所以整個的這種運行機制又稱為 Event Loop(事件迴圈)。只要主線程空了,就會去讀取"任務隊列",這就是 JavaScript 的運行機制。

      說完 JS 主線程的執行機制,下麵說說經常被問到的 JS 非同步中 巨集任務(macrotasks)、微任務(microtasks)執行順序。JS 非同步有一個機制,就是遇到巨集任務,先執行巨集任務,將巨集任務放入 Event Queue,然後再執行微任務,將微任務放入 Event Queue,但是,這兩個 Queue 不是一個 Queue。當你往外拿的時候先從微任務里拿這個回調函數,然後再從巨集任務的 Queue 拿巨集任務的回調函數。如下圖:
JS非同步

巨集任務:整體代碼 script,setTimeout,setInterval

微任務:Promise,process.nextTick

參考鏈接:這一次,徹底弄懂 JavaScript 執行機制

回到頂部

介紹下 promise.all

      Promise.all()方法將多個Promise實例包裝成一個Promise對象(p),接受一個數組(p1,p2,p3)作為參數,數組中不一定需要都是Promise對象,但是一定具有Iterator介面,如果不是的話,就會調用Promise.resolve將其轉化為Promise對象之後再進行處理。
      使用Promise.all()生成的Promise對象(p)的狀態是由數組中的Promise對象(p1,p2,p3)決定的。

  1. 如果所有的Promise對象(p1,p2,p3)都變成fullfilled狀態的話,生成的Promise對象(p)也會變成fullfilled狀態,
    p1,p2,p3三個Promise對象產生的結果會組成一個數組返回給傳遞給p的回調函數。
  2. 如果p1,p2,p3中有一個Promise對象變為rejected狀態的話,p也會變成rejected狀態,第一個被rejected的對象的返回值會傳遞給p的回調函數。
    Promise.all()方法生成的Promise對象也會有一個catch方法來捕獲錯誤處理,但是如果數組中的Promise對象變成rejected狀態時,
    並且這個對象還定義了catch的方法,那麼rejected的對象會執行自己的catch方法。
    並且返回一個狀態為fullfilled的Promise對象,Promise.all()生成的對象會接受這個Promise對象,不會返回rejected狀態。
回到頂部

async 和 await

主要考察巨集任務和微任務,搭配promise,詢問一些輸出的順序

原理:async 和 await 用了同步的方式去做非同步,async 定義的函數的返回值都是 promise,await 後面的函數會先執行一遍,然後就會跳出整個 async 函數來執行後面js棧的代碼

回到頂部

ES6 的 class 和構造函數的區別

class 的寫法只是語法糖,和之前 prototype 差不多,但還是有細微差別的,下麵看看:

1. 嚴格模式

類和模塊的內部,預設就是嚴格模式,所以不需要使用use strict指定運行模式。只要你的代碼寫在類或模塊之中,就只有嚴格模式可用。考慮到未來所有的代碼,其實都是運行在模塊之中,所以 ES6 實際上把整個語言升級到了嚴格模式。

2. 不存在提升

類不存在變數提升(hoist),這一點與 ES5 完全不同。

複製new Foo(); // ReferenceError
class Foo {}
3. 方法預設是不可枚舉的

ES6 中的 class,它的方法(包括靜態方法和實例方法)預設是不可枚舉的,而構造函數預設是可枚舉的。細想一下,這其實是個優化,讓你在遍歷時候,不需要再判斷 hasOwnProperty 了

4. class 的所有方法(包括靜態方法和實例方法)都沒有原型對象 prototype,所以也沒有[[construct]],不能使用 new 來調用。
5. class 必須使用 new 調用,否則會報錯。這是它跟普通構造函數的一個主要區別,後者不用 new 也可以執行。
6. ES5 和 ES6 子類 this 生成順序不同

ES5 的繼承先生成了子類實例,再調用父類的構造函數修飾子類實例。ES6 的繼承先 生成父類實例,再調用子類的構造函數修飾父類實例。這個差別使得 ES6 可以繼承內置對象。

7. ES6可以繼承靜態方法,而構造函數不能
回到頂部

transform、translate、transition 分別是什麼屬性?CSS 中常用的實現動畫方式

三者屬性說明
transform 是指變換、變形,是 css3 的一個屬性,和 width,height 屬性一樣;
translate 是 transform 的屬性值,是指元素進行 2D(3D)維度上位移或範圍變換;
transition 是指過渡效果,往往理解成簡單的動畫,需要有觸發條件。

這裡可以補充下 transition 和 animation 的比較,前者一般定義開始結束兩個狀態,需要有觸發條件;而後者引入了關鍵幀、速度曲線、播放次數等概念,更符合動畫的定義,且無需觸發條件

回到頂部

介紹一下rAF(requestAnimationFrame)

      專門用來做動畫,不卡頓,用法和setTimeout一樣。對 rAF 的闡述 MDN 資料

      定時器一直是 js 動畫的核心技術,但它們不夠精準,因為定時器時間參數是指將執行代碼放入 UI 線程隊列中等待的時間,如果前面有其他任務隊列執行時間過長,則會導致動畫延遲,效果不精確等問題。
      所以處理動畫迴圈的關鍵是知道延遲多長時間合適:時間要足夠短,才能讓動畫看起來比較柔滑平順,避免多餘性能損耗;時間要足夠長,才能讓瀏覽器準備好變化渲染。這個時候 rAF 就出現了,採用系統時間間隔(大多瀏覽器刷新頻率是 60Hz,相當於 1000ms/60≈16.6ms),保持最佳繪製效率,不會因為間隔時間過短,造成過度繪製,增加開銷;也不會因為間隔時間太長,使用動畫卡頓不流暢,讓各種網頁動畫效果能夠有一個統一的刷新機制。並且 rAF 會把每一幀中的所有 DOM 操作集中起來,在一次重繪或迴流中就完成。

詳情:CSS3動畫那麼強,requestAnimationFrame還有毛線用?

回到頂部

javascript 的垃圾回收機制講一下

定義:指一塊被分配的記憶體既不能使用,又不能回收,直到瀏覽器進程結束。

像 C 這樣的編程語言,具有低級記憶體管理原語,如 malloc()和 free()。開發人員使用這些原語顯式地對操作系統的記憶體進行分配和釋放。
而 JavaScript 在創建對象(對象、字元串等)時會為它們分配記憶體,不再使用對時會“自動”釋放記憶體,這個過程稱為垃圾收集。

記憶體生命周期中的每一個階段:

分配記憶體 —  記憶體是由操作系統分配的,它允許您的程式使用它。在低級語言(例如 C 語言)中,這是一個開發人員需要自己處理的顯式執行的操作。然而,在高級語言中,系統會自動為你分配內在。
使用記憶體 — 這是程式實際使用之前分配的記憶體,在代碼中使用分配的變數時,就會發生讀和寫操作。
釋放記憶體 — 釋放所有不再使用的記憶體,使之成為自由記憶體,並可以被重利用。與分配記憶體操作一樣,這一操作在低級語言中也是需要顯式地執行。

四種常見的記憶體泄漏:全局變數,未清除的定時器,閉包,以及 dom 的引用
  1. 全局變數 不用 var 聲明的變數,相當於掛載到 window 對象上。如:b=1; 解決:使用嚴格模式
  2. 被遺忘的定時器和回調函數
  3. 閉包
  4. 沒有清理的 DOM 元素引用
回到頂部

對前端性能優化有什麼瞭解?一般都通過那幾個方面去優化的?

前端性能優化的七大手段

  1. 減少請求數量
  2. 減小資源大小
  3. 優化網路連接
  4. 優化資源載入
  5. 減少重繪迴流
  6. 性能更好的API
  7. webpack優化

前端安全也經常被問到的,常見的有兩種——XSS、CSRF,詳見前端安全

2019前端面試系列——CSS面試題
2019前端面試系列——JS面試題
2019前端面試系列——JS高頻手寫代碼題
2019前端面試系列——Vue面試題
2019前端面試系列——HTTP、瀏覽器面試題


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • if條件判斷語句:條件成立,執行什麼代碼;條件不成立,執行什麼代碼結構一:只判斷真(true),條件為假,什麼也不做if(條件判斷:判斷結果是一個布爾值){條件為真(true),執行的代碼} 結構二:既判斷真,也判斷假 if(條件判斷){條件為真,執行的代碼}else{條件為假,執行的代碼} 結構三 ...
  • Koch曲線的構造過程是:取一條長度為L0的直線段,將其三等分,保留兩端的線段,將中間的一段改換成夾角為60度的兩個等長直線;再將長度為L0/3的4個直線段分別進行三等分,並將它們中間的一段均改換成夾角為60度的兩段長為L0/9的直線段;重覆以上操作直至無窮,可得以一條具有自相似結構的折線,如圖1所 ...
  • 1 問題 當使用pdfjs來實現預覽功能的時候,遇到了2個問題: 一是帶寬占用過大,會下載整個pdf文件,這對部署在公網的應用來說,成本壓力很大,因為雲服務帶寬是很貴的。 二是記憶體占用過大,一個80M的pdf,在預覽時占用記憶體高達600M,在一些記憶體較小的手機上容易發生崩潰。 pdfjs預設配置下, ...
  • 1.圖片標簽 img src:圖片路徑 width:設置圖片的寬度,如果是單獨設置,則保存圖片比例進行修改,單位可以是px和% height:設置圖片的高度,如果是單獨設置,則保存圖片比例進行修改,單位可以是px和% title:滑鼠放在圖片上提示圖片名稱 alt:當圖片路徑有誤的時候用來提示 路徑 ...
  • 關於HTML中的 <!DOCTYPE> 聲明 今天在完成課程任務時,我的HTML代碼中一處出現了一個問題。 我現在有三張圖片,這三張圖片是從一張圖片無縫裁剪下來的,這三張圖片均等寬不等高,若使用PS可完美拼接回原圖。我在表格內,將此三張圖片放入,當瀏覽器運行時,我發現此三圖片並未完美緊密貼合,而是兩 ...
  • 元編程是一種強大的技術,使你能夠編寫可以創建其他程式的程式。ES6藉助代理和許多類似功能,使在JavaScript中利用元編程變得更加容易。ES6 Proxy(代理) 有助於重新定義對象的基本操作,從而為各種可能性打開了大門。 本指南可以幫助您理解為什麼ES6代理如此之好,尤其是對於元編程而言: 什 ...
  • 1.HTML的head標簽 head標簽中主要配置瀏覽器的配置信息 常用的配置信息: 1.網頁解析編碼格式 2.網頁標題標簽 3.網頁關鍵字 4.網頁描述 5.作者 6.自動跳轉 7.其他(引入css,js) 註:其中第三,第四和第五項,提升在瀏覽器中的搜索概率 例: 2.HTML的body標簽(文 ...
  • 憑藉應用廣泛、入門簡單的優勢,Web前端吸引了人們的廣泛關註。學習Web前端就業薪資高,因此很多人都想入門前端開發行業。 零基礎自學Web前端,你需要具備以下幾點: 1、耐性。要成為優秀的web前端開發者,要調整好心態。拋開一切的方法和技術知識,最重要的就是你的耐性。 2、學會延伸。對於新手來說,新 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...