日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 頭號(hào)碼甲 2021-10-07
 

判斷 js 類型的方式

1. typeof

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

2. instanceof

原理是 構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在對(duì)象的原型鏈中的任何位置

復(fù)制function A() {}
let a = new A();
a instanceof A     //true,因?yàn)?Object.getPrototypeOf(a) === A.prototype;
3. Object.prototype.toString.call()

常用于判斷瀏覽器內(nèi)置對(duì)象,對(duì)于所有基本的數(shù)據(jù)類型都能進(jìn)行判斷,即使是 null 和 undefined

4. Array.isArray()

用于判斷是否為數(shù)組

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

ES5 有倆種:varfunction
ES6 有六種:增加四種,letconst、classimport

注意:let、const、class聲明的全局變量再也不會(huì)和全局對(duì)象的屬性掛鉤

閉包的概念?優(yōu)缺點(diǎn)?

閉包的概念:閉包就是能讀取其他函數(shù)內(nèi)部變量的函數(shù)。

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

  1. 避免全局變量的污染
  2. 希望一個(gè)變量長期存儲(chǔ)在內(nèi)存中(緩存變量)

缺點(diǎn):

  1. 內(nèi)存泄露(消耗)
  2. 常駐內(nèi)存,增加內(nèi)存使用量

淺拷貝和深拷貝

  • 淺拷貝
復(fù)制// 第一層為深拷貝
Object.assign()
Array.prototype.slice()
擴(kuò)展運(yùn)算符 ...
  • 深拷貝
復(fù)制JSON.parse(JSON.stringify())

遞歸函數(shù)

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

如何實(shí)現(xiàn)一個(gè)深拷貝
詳細(xì)解析賦值、淺拷貝和深拷貝的區(qū)別

數(shù)組去重的方法

1.ES6 的 Set
復(fù)制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()
復(fù)制// 這種方法會(huì)有一個(gè)問題:[1,'1']會(huì)被當(dāng)做相同元素,最終輸入[1]
let arr = [1,1,2,3,4,5,5,6]
let arr2 = arr.filter(function(item,index) {
  // indexOf() 方法可返回某個(gè)指定的 字符串值 在字符串中首次出現(xiàn)的位置
  return arr.indexOf(item) === index
})

DOM 事件有哪些階段?談?wù)剬?duì)事件代理的理解

分為三大階段:捕獲階段--目標(biāo)階段--冒泡階段

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

好處:(1)使代碼更簡潔;(2)節(jié)省內(nèi)存開銷

js 執(zhí)行機(jī)制、事件循環(huán)

      JavaScript 語言的一大特點(diǎn)就是單線程,同一個(gè)時(shí)間只能做一件事。單線程就意味著,所有任務(wù)需要排隊(duì),前一個(gè)任務(wù)結(jié)束,才會(huì)執(zhí)行后一個(gè)任務(wù)。如果前一個(gè)任務(wù)耗時(shí)很長,后一個(gè)任務(wù)就不得不一直等著。JavaScript 語言的設(shè)計(jì)者意識(shí)到這個(gè)問題,將所有任務(wù)分成兩種,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous),在所有同步任務(wù)執(zhí)行完之前,任何的異步任務(wù)是不會(huì)執(zhí)行的。
      當(dāng)我們打開網(wǎng)站時(shí),網(wǎng)頁的渲染過程就是一大堆同步任務(wù),比如頁面骨架和頁面元素的渲染。而像加載圖片音樂之類占用資源大耗時(shí)久的任務(wù),就是異步任務(wù)。關(guān)于這部分有嚴(yán)格的文字定義,但本文的目的是用最小的學(xué)習(xí)成本徹底弄懂執(zhí)行機(jī)制,所以我們用導(dǎo)圖來說明:
js執(zhí)行機(jī)制

導(dǎo)圖要表達(dá)的內(nèi)容用文字來表述的話:
      同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行"場所",同步的進(jìn)入主線程,異步的進(jìn)入 Event Table 并注冊(cè)函數(shù)。當(dāng)指定的事情完成時(shí),Event Table 會(huì)將這個(gè)函數(shù)移入 Event Queue。主線程內(nèi)的任務(wù)執(zhí)行完畢為空,會(huì)去 Event Queue 讀取對(duì)應(yīng)的函數(shù),進(jìn)入主線程執(zhí)行。上述過程會(huì)不斷重復(fù),也就是常說的 Event Loop(事件循環(huán))。
      我們不禁要問了,那怎么知道主線程執(zhí)行棧為空???js 引擎存在 monitoring process 進(jìn)程,會(huì)持續(xù)不斷的檢查主線程執(zhí)行棧是否為空,一旦為空,就會(huì)去 Event Queue 那里檢查是否有等待被調(diào)用的函數(shù)。換一張圖片也許更好理解主線程的執(zhí)行過程:


      上圖用文字表述就是:主線程從"任務(wù)隊(duì)列"中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為 Event Loop(事件循環(huán))。只要主線程空了,就會(huì)去讀取"任務(wù)隊(duì)列",這就是 JavaScript 的運(yùn)行機(jī)制。

      說完 JS 主線程的執(zhí)行機(jī)制,下面說說經(jīng)常被問到的 JS 異步中 宏任務(wù)(macrotasks)、微任務(wù)(microtasks)執(zhí)行順序。JS 異步有一個(gè)機(jī)制,就是遇到宏任務(wù),先執(zhí)行宏任務(wù),將宏任務(wù)放入 Event Queue,然后再執(zhí)行微任務(wù),將微任務(wù)放入 Event Queue,但是,這兩個(gè) Queue 不是一個(gè) Queue。當(dāng)你往外拿的時(shí)候先從微任務(wù)里拿這個(gè)回調(diào)函數(shù),然后再從宏任務(wù)的 Queue 拿宏任務(wù)的回調(diào)函數(shù)。如下圖:
JS異步

宏任務(wù):整體代碼 script,setTimeout,setInterval

微任務(wù):Promise,process.nextTick

參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制

介紹下 promise.all

      Promise.all()方法將多個(gè)Promise實(shí)例包裝成一個(gè)Promise對(duì)象(p),接受一個(gè)數(shù)組(p1,p2,p3)作為參數(shù),數(shù)組中不一定需要都是Promise對(duì)象,但是一定具有Iterator接口,如果不是的話,就會(huì)調(diào)用Promise.resolve將其轉(zhuǎn)化為Promise對(duì)象之后再進(jìn)行處理。
      使用Promise.all()生成的Promise對(duì)象(p)的狀態(tài)是由數(shù)組中的Promise對(duì)象(p1,p2,p3)決定的。

  1. 如果所有的Promise對(duì)象(p1,p2,p3)都變成fullfilled狀態(tài)的話,生成的Promise對(duì)象(p)也會(huì)變成fullfilled狀態(tài),
    p1,p2,p3三個(gè)Promise對(duì)象產(chǎn)生的結(jié)果會(huì)組成一個(gè)數(shù)組返回給傳遞給p的回調(diào)函數(shù)。
  2. 如果p1,p2,p3中有一個(gè)Promise對(duì)象變?yōu)閞ejected狀態(tài)的話,p也會(huì)變成rejected狀態(tài),第一個(gè)被rejected的對(duì)象的返回值會(huì)傳遞給p的回調(diào)函數(shù)。
    Promise.all()方法生成的Promise對(duì)象也會(huì)有一個(gè)catch方法來捕獲錯(cuò)誤處理,但是如果數(shù)組中的Promise對(duì)象變成rejected狀態(tài)時(shí),
    并且這個(gè)對(duì)象還定義了catch的方法,那么rejected的對(duì)象會(huì)執(zhí)行自己的catch方法。
    并且返回一個(gè)狀態(tài)為fullfilled的Promise對(duì)象,Promise.all()生成的對(duì)象會(huì)接受這個(gè)Promise對(duì)象,不會(huì)返回rejected狀態(tài)。

async 和 await

主要考察宏任務(wù)和微任務(wù),搭配promise,詢問一些輸出的順序

原理:async 和 await 用了同步的方式去做異步,async 定義的函數(shù)的返回值都是 promise,await 后面的函數(shù)會(huì)先執(zhí)行一遍,然后就會(huì)跳出整個(gè) async 函數(shù)來執(zhí)行后面js棧的代碼

ES6 的 class 和構(gòu)造函數(shù)的區(qū)別

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

1. 嚴(yán)格模式

類和模塊的內(nèi)部,默認(rèn)就是嚴(yán)格模式,所以不需要使用use strict指定運(yùn)行模式。只要你的代碼寫在類或模塊之中,就只有嚴(yán)格模式可用。考慮到未來所有的代碼,其實(shí)都是運(yùn)行在模塊之中,所以 ES6 實(shí)際上把整個(gè)語言升級(jí)到了嚴(yán)格模式。

2. 不存在提升

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

復(fù)制new Foo(); // ReferenceError
class Foo {}
3. 方法默認(rèn)是不可枚舉的

ES6 中的 class,它的方法(包括靜態(tài)方法和實(shí)例方法)默認(rèn)是不可枚舉的,而構(gòu)造函數(shù)默認(rèn)是可枚舉的。細(xì)想一下,這其實(shí)是個(gè)優(yōu)化,讓你在遍歷時(shí)候,不需要再判斷 hasOwnProperty 了

4. class 的所有方法(包括靜態(tài)方法和實(shí)例方法)都沒有原型對(duì)象 prototype,所以也沒有[[construct]],不能使用 new 來調(diào)用。
5. class 必須使用 new 調(diào)用,否則會(huì)報(bào)錯(cuò)。這是它跟普通構(gòu)造函數(shù)的一個(gè)主要區(qū)別,后者不用 new 也可以執(zhí)行。
6. ES5 和 ES6 子類 this 生成順序不同

ES5 的繼承先生成了子類實(shí)例,再調(diào)用父類的構(gòu)造函數(shù)修飾子類實(shí)例。ES6 的繼承先 生成父類實(shí)例,再調(diào)用子類的構(gòu)造函數(shù)修飾父類實(shí)例。這個(gè)差別使得 ES6 可以繼承內(nèi)置對(duì)象。

7. ES6可以繼承靜態(tài)方法,而構(gòu)造函數(shù)不能

transform、translate、transition 分別是什么屬性?CSS 中常用的實(shí)現(xiàn)動(dòng)畫方式

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

這里可以補(bǔ)充下 transition 和 animation 的比較,前者一般定義開始結(jié)束兩個(gè)狀態(tài),需要有觸發(fā)條件;而后者引入了關(guān)鍵幀、速度曲線、播放次數(shù)等概念,更符合動(dòng)畫的定義,且無需觸發(fā)條件

介紹一下rAF(requestAnimationFrame)

      專門用來做動(dòng)畫,不卡頓,用法和setTimeout一樣。對(duì) rAF 的闡述 MDN 資料

      定時(shí)器一直是 js 動(dòng)畫的核心技術(shù),但它們不夠精準(zhǔn),因?yàn)槎〞r(shí)器時(shí)間參數(shù)是指將執(zhí)行代碼放入 UI 線程隊(duì)列中等待的時(shí)間,如果前面有其他任務(wù)隊(duì)列執(zhí)行時(shí)間過長,則會(huì)導(dǎo)致動(dòng)畫延遲,效果不精確等問題。
      所以處理動(dòng)畫循環(huán)的關(guān)鍵是知道延遲多長時(shí)間合適:時(shí)間要足夠短,才能讓動(dòng)畫看起來比較柔滑平順,避免多余性能損耗;時(shí)間要足夠長,才能讓瀏覽器準(zhǔn)備好變化渲染。這個(gè)時(shí)候 rAF 就出現(xiàn)了,采用系統(tǒng)時(shí)間間隔(大多瀏覽器刷新頻率是 60Hz,相當(dāng)于 1000ms/60≈16.6ms),保持最佳繪制效率,不會(huì)因?yàn)殚g隔時(shí)間過短,造成過度繪制,增加開銷;也不會(huì)因?yàn)殚g隔時(shí)間太長,使用動(dòng)畫卡頓不流暢,讓各種網(wǎng)頁動(dòng)畫效果能夠有一個(gè)統(tǒng)一的刷新機(jī)制。并且 rAF 會(huì)把每一幀中的所有 DOM 操作集中起來,在一次重繪或回流中就完成。

詳情:CSS3動(dòng)畫那么強(qiáng),requestAnimationFrame還有毛線用?

javascript 的垃圾回收機(jī)制講一下

定義:指一塊被分配的內(nèi)存既不能使用,又不能回收,直到瀏覽器進(jìn)程結(jié)束。

像 C 這樣的編程語言,具有低級(jí)內(nèi)存管理原語,如 malloc()和 free()。開發(fā)人員使用這些原語顯式地對(duì)操作系統(tǒng)的內(nèi)存進(jìn)行分配和釋放。
而 JavaScript 在創(chuàng)建對(duì)象(對(duì)象、字符串等)時(shí)會(huì)為它們分配內(nèi)存,不再使用對(duì)時(shí)會(huì)“自動(dòng)”釋放內(nèi)存,這個(gè)過程稱為垃圾收集。

內(nèi)存生命周期中的每一個(gè)階段:

分配內(nèi)存 —? 內(nèi)存是由操作系統(tǒng)分配的,它允許您的程序使用它。在低級(jí)語言(例如 C 語言)中,這是一個(gè)開發(fā)人員需要自己處理的顯式執(zhí)行的操作。然而,在高級(jí)語言中,系統(tǒng)會(huì)自動(dòng)為你分配內(nèi)在。
使用內(nèi)存 — 這是程序?qū)嶋H使用之前分配的內(nèi)存,在代碼中使用分配的變量時(shí),就會(huì)發(fā)生讀和寫操作。
釋放內(nèi)存 — 釋放所有不再使用的內(nèi)存,使之成為自由內(nèi)存,并可以被重利用。與分配內(nèi)存操作一樣,這一操作在低級(jí)語言中也是需要顯式地執(zhí)行。

四種常見的內(nèi)存泄漏:全局變量,未清除的定時(shí)器,閉包,以及 dom 的引用
  1. 全局變量 不用 var 聲明的變量,相當(dāng)于掛載到 window 對(duì)象上。如:b=1; 解決:使用嚴(yán)格模式
  2. 被遺忘的定時(shí)器和回調(diào)函數(shù)
  3. 閉包
  4. 沒有清理的 DOM 元素引用

對(duì)前端性能優(yōu)化有什么了解?一般都通過那幾個(gè)方面去優(yōu)化的?

前端性能優(yōu)化的七大手段

  1. 減少請(qǐng)求數(shù)量
  2. 減小資源大小
  3. 優(yōu)化網(wǎng)絡(luò)連接
  4. 優(yōu)化資源加載
  5. 減少重繪回流
  6. 性能更好的API
  7. webpack優(yōu)化

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

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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多