前端面試題(2022)

html

1.1 html標(biāo)簽的類型(head, body执赡,甚亭!Doctype) 他們的作用是什么

參考答案:

!DOCTYPE 標(biāo)簽:

  • 它是指示 web 瀏覽器關(guān)于頁面使用哪個 HTML 版本進(jìn)行編寫的指令.

head:

  • 是所有頭部元素的容器, 絕大多數(shù)頭部標(biāo)簽的內(nèi)容不會顯示給讀者
  • 該標(biāo)簽下所包含的部分可加入的標(biāo)簽有,,,,和

body :

  • 用于定義文檔的主體, 包含了文檔的所有內(nèi)容
  • 該標(biāo)簽支持 html 的全局屬性和事件屬性.

1.2 h5新特性

參考答案:

  • 新增選擇器 document.querySelector、document.querySelectorAll
  • 拖拽釋放(Drag and drop) API
  • 媒體播放的 video 和 audio
  • 本地存儲 localStorage 和 sessionStorage
  • 離線應(yīng)用 manifest
  • 桌面通知 Notifications
  • 語意化標(biāo)簽 article、footer截驮、header、nav际度、section
  • 增強(qiáng)表單控件 calendar葵袭、date、time乖菱、email坡锡、url、search
  • 地理位置 Geolocation
  • 多任務(wù) webworker
  • 全雙工通信協(xié)議 websocket
  • 歷史管理 history
  • 跨域資源共享(CORS) Access-Control-Allow-Origin
  • 頁面可見性改變事件 visibilitychange
  • 跨窗口通信 PostMessage
  • Form Data 對象
  • 繪畫 canvas

H5移除的元素:

  • 純表現(xiàn)的元素:basefont窒所、big鹉勒、center、font墩新、s贸弥、strike窟坐、tt海渊、u
  • 對可用性產(chǎn)生負(fù)面影響的元素:frame、frameset哲鸳、noframes

1.3 偽類和偽元素

參考答案:

偽類:用于已有元素處于某種狀態(tài)時為其添加對應(yīng)的樣式臣疑,這個狀態(tài)是根據(jù)用戶行為而動態(tài)變化的。

例如:當(dāng)用戶懸停在指定元素時徙菠,可以通過:hover來描述這個元素的狀態(tài)讯沈,雖然它和一般css相似,可以為 已有元素添加樣式婿奔,但是它只有處于DOM樹無法描述的狀態(tài)下才能為元素添加樣式缺狠,所以稱為偽類。

偽元素:用于創(chuàng)建一些不在DOM樹中的元素萍摊,并為其添加樣式挤茄。

例如,我們可以通過:before來在一個元素之前添加一些文本冰木,并為這些文本添加樣式穷劈,雖然用戶可以看見 這些文本,但是它實(shí)際上并不在DOM文檔中踊沸。

1.4 html5語義化

參考答案:

在HTML5出來之前歇终,我們習(xí)慣于用div來表示頁面的章節(jié)或者不同模塊,但是div本身是沒有語義的逼龟。但是現(xiàn)在评凝,HTML5中加入了一些語義化標(biāo)簽,來更清晰的表達(dá)文檔結(jié)構(gòu)腺律。

語義化優(yōu)點(diǎn):

  • 易于用戶閱讀肥哎,樣式丟失的時候能讓頁面呈現(xiàn)清晰的結(jié)構(gòu)辽俗。
  • 有利于SEO,搜索引擎根據(jù)標(biāo)簽來確定上下文和各個關(guān)鍵字的權(quán)重篡诽。
  • 方便屏幕閱讀器解析崖飘,如盲人閱讀器根據(jù)語義渲染網(wǎng)頁
  • 有利于開發(fā)和維護(hù),語義化更具可讀性杈女,代碼更好維護(hù)朱浴,與CSS3關(guān)系更和諧。

1.5 audio 標(biāo)簽的api

參考答案:

audio常用屬性
src :播放的音樂的url地址(火狐只支持ogg的音樂达椰,而IE9只支持MP3格式的音樂翰蠢。chrome貌似全支持)
preload:預(yù)加載(在頁面被加載時進(jìn)行加載或者說緩沖音頻),如果使用了autoplay的話那么該屬性失效啰劲。
loop:循環(huán)播放
controls: 是否顯示默認(rèn)控制條(控制按鈕)
autoplay:自動播放

audio屬性
duration: 獲取媒體文件的總時長梁沧,以s為單位,如果無法獲取蝇裤,返回NaN
paused :如果媒體文件被暫停廷支,那么paused屬性返回true,反之則返回false
ended: 如果媒體文件播放完畢返回true
muted:用來獲取或設(shè)置靜音狀態(tài)栓辜。值為boolean
volume:控制音量的屬性值為0-1;0為音量最小恋拍,1為音量最大
startTime:返回起始播放時間
error:返回錯誤代碼,為uull的時候?yàn)檎E核Α7駝t可以通過Music.error.code來獲取具體的錯誤代碼: 1.用戶終止 2.網(wǎng)絡(luò)錯誤 3.解碼錯誤 4.URL無效
currentTime:用來獲取或控制當(dāng)前播放的時間施敢,單位為s。
currentSrc:以字符串形式返回正在播放或已加載的文件

常用的控制用的函數(shù):
load() :加載音頻狭莱、視頻軟件
play():加載并播放音頻僵娃、視頻文件或重新播放暫停的的音頻、視頻
pause():暫停出于播放狀態(tài)的音頻腋妙、視頻文件
canPlayType(obj) :測試是否支持給定的Mini類型的文件

常用audio的事件:
loadstart:客戶端開始請求數(shù)據(jù)
progress:客戶端正在請求數(shù)據(jù)(或者說正在緩沖)
play:play()和autoplay播放時
pausepause():方法促發(fā)時
ended:當(dāng)前播放結(jié)束
timeupdate:當(dāng)前播放時間發(fā)生改變的時候默怨。播放中常用的時間處理哦
canplaythrough:歌曲已經(jīng)載入完全完成
canplay:緩沖至目前可播放狀態(tài)。

js

2. js基礎(chǔ)

2.1 let const var 相關(guān)

參考答案:

var ——ES5 變量聲明方式

  1. 在變量未賦值時辉阶,變量undefined(為使用聲明變量時也為undefined)
  2. 作用域——var的作用域?yàn)榉椒ㄗ饔糜蛳群荆恢灰诜椒▋?nèi)定義了,整個方法內(nèi)的定義變量后的代碼都可以使用

let——ES6變量聲明方式

  1. 在變量為聲明前直接使用會報錯
  2. 作用域——let為塊作用域——通常let比var 范圍要小
  3. let禁止重復(fù)聲明變量谆甜,否則會報錯垃僚;var可以重復(fù)聲明

const——ES6變量聲明方式

1. const為常量聲明方式;聲明變量時必須初始化规辱,在后面出現(xiàn)的代碼中不能再修改該常量的值

2. const實(shí)際上保證的谆棺,并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址不得改動

2.2 js數(shù)據(jù)類型,區(qū)別

參考答案:

基本數(shù)據(jù)類型:

Number改淑,String碍岔,Boolean,null朵夏,undefined蔼啦,symbol,bigint(后兩個為ES6新增)

引用數(shù)據(jù)類型:

object仰猖,function(proto Function.prototype)

object:普通對象捏肢,數(shù)組對象,正則對象饥侵,日期對象鸵赫,Math數(shù)學(xué)函數(shù)對象。

兩種數(shù)據(jù)存儲方式:

基本數(shù)據(jù)類型是直接存儲在棧中的簡單數(shù)據(jù)段躏升,占據(jù)空間小辩棒、大小固定,屬于被頻繁使用的數(shù)據(jù)膨疏。棧是存儲基 本類型值和執(zhí)行代碼的空間一睁。

引用數(shù)據(jù)類型是存儲在堆內(nèi)存中,占據(jù)空間大成肘、大小不固定卖局。引用數(shù)據(jù)類型在棧中存儲了指針斧蜕,該指針指向堆 中該實(shí)體的起始地址双霍,當(dāng)解釋器尋找引用值時,會檢索其在棧中的地址批销,取得地址后從堆中獲得實(shí)體洒闸。

兩種數(shù)據(jù)類型的區(qū)別:

  1. 堆比棧空間大均芽,棧比堆運(yùn)行速度快丘逸。

  2. 堆內(nèi)存是無序存儲,可以根據(jù)引用直接獲取掀宋。

  3. 基礎(chǔ)數(shù)據(jù)類型比較穩(wěn)定深纲,而且相對來說占用的內(nèi)存小。

  4. 引用數(shù)據(jù)類型大小是動態(tài)的劲妙,而且是無限的湃鹊。

2.3 Object.assign的理解

參考答案:

作用:Object.assign可以實(shí)現(xiàn)對象的合并。

語法:Object.assign(target, ...sources)

解析

  1. Object.assign會將source里面的可枚舉屬性復(fù)制到target镣奋,如果和target的已有屬性重名币呵,則會覆蓋。
  2. 后續(xù)的source會覆蓋前面的source的同名屬性侨颈。
  3. Object.assign復(fù)制的是屬性值余赢,如果屬性值是一個引用類型芯义,那么復(fù)制的其實(shí)是引用地址,就會存在引用共享的問題妻柒。

2.4 constructor的理解

參考答案:

創(chuàng)建的每個函數(shù)都有一個prototype(原型)對象扛拨,這個屬性是一個指針,指向一個對象举塔。在默認(rèn)情況下鬼癣,所有原型對象都會自動獲得一個constructor(構(gòu)造函數(shù))屬性,這個屬性是一個指向prototype屬性所在函數(shù)的指針啤贩。當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個新實(shí)例后待秃,該實(shí)例的內(nèi)部將包含一個指針(繼承自構(gòu)造函數(shù)的prototype),指向構(gòu)造函數(shù)的原型對象痹屹。注意當(dāng)將構(gòu)造函數(shù)的prototype設(shè)置為等于一個以對象字面量形式創(chuàng)建的新對象時章郁,constructor屬性不再指向該構(gòu)造函數(shù)。

2.5 map 和 forEach 的區(qū)別

參考答案:

相同點(diǎn):

  1. 都是循環(huán)遍歷數(shù)組中的每一項(xiàng)

  2. 每次執(zhí)行匿名函數(shù)都支持三個參數(shù)志衍,參數(shù)分別為item(當(dāng)前每一項(xiàng))暖庄,index(索引值),arr(原數(shù)組)

  3. 匿名函數(shù)中的this都是指向window

  4. 只能遍歷數(shù)組

不同點(diǎn):

  1. map()會分配內(nèi)存空間存儲新數(shù)組并返回楼肪,forEach()不會返回數(shù)據(jù)培廓。

  2. forEach()允許callback更改原始數(shù)組的元素。map()返回新的數(shù)組春叫。

2.6 for of 可以遍歷哪些對象

參考答案:

for..of..: 它是es6新增的一個遍歷方法肩钠,但只限于迭代器(iterator), 所以普通的對象用for..of遍歷
是會報錯的。

可迭代的對象:包括Array, Map, Set, String, TypedArray, arguments對象等等

2.7 js靜態(tài)類型檢查

參考答案:

js是動態(tài)類型語言

靜態(tài)類型語言 & 動態(tài)類型語言

靜態(tài)類型語言:類型檢查發(fā)生在編譯階段暂殖,因此除非修復(fù)錯誤价匠,否則會一直編譯失敗

動態(tài)類型語言:只有在程序運(yùn)行了一次的時候錯誤才會被發(fā)現(xiàn),也就是在運(yùn)行時呛每,因此即使代碼中包含了會 在運(yùn)行時阻止腳本正常運(yùn)行的錯誤類型踩窖,這段代碼也可以通過編譯

js靜態(tài)類型檢查的方法

Flow是Facebook開發(fā)和發(fā)布的一個開源的靜態(tài)類型檢查庫,它允許你逐漸地向JavaScript代碼中添加類型晨横。

TypeScript是一個會編譯為JavaScript的超集(盡管它看起來幾乎像一種新的靜態(tài)類型語言)

使用靜態(tài)類型的優(yōu)勢

  • 可以盡早發(fā)現(xiàn)bug和錯誤
  • 減少了復(fù)雜的錯誤處理
  • 將數(shù)據(jù)和行為分離
  • 減少單元測試的數(shù)量
  • 提供了領(lǐng)域建模(domain modeling)工具
  • 幫助我們消除了一整類bug
  • 重構(gòu)時更有信心

使用靜態(tài)類型的劣勢

  • 代碼冗長
  • 需要花時間去掌握類型

2.8 indexof

參考答案:

語法:str.indexOf(searchValue [, fromIndex])

參數(shù):searchValue:要被查找的字符串值洋腮。

如果沒有提供確切地提供字符串,[searchValue 會被強(qiáng)制設(shè)置為"undefined"]手形, 然后在當(dāng)前字符串中查 找這個值啥供。

舉個例子:'undefined'.indexOf()將會返回0,因?yàn)閡ndefined在位置0處被找到叁幢,但是'undefine'.indexOf()將會返回 -1 滤灯,因?yàn)樽址?undefined'未被找到

fromIndex:可選

數(shù)字表示開始查找的位置。可以是任意整數(shù)鳞骤,默認(rèn)值為0窒百。

如果fromIndex的值小于0,或者大于str.length豫尽,那么查找分別從0和str.length開始篙梢。(譯者 注:fromIndex的值小于0,等同于為空情況美旧;fromIndex的值大于或等于str.length渤滞,那么結(jié)果 會直接返回-1。)

舉個例子榴嗅,'hello world'.indexOf('o', -5)返回4妄呕,因?yàn)樗菑奈恢?處開始查找,然后o在位置4處被找到嗽测。另一方面绪励,'hello world'.indexOf('o', 11)(或fromIndex填入任何大于11的值) 將會返回-1,因?yàn)殚_始查找的位置11處唠粥,已經(jīng)是這個字符串的結(jié)尾了疏魏。

返回值:

查找的字符串searchValue的第一次出現(xiàn)的索引,如果沒有找到晤愧,則返回-1大莫。

若被查找的字符串searchValue是一個空字符串,則返回fromIndex官份。如果fromIndex值為空只厘,或者fromIndex值小于被查找的字符串的長度,返回值和以下的fromIndex值一樣贯吓。

如果fromIndex值大于等于字符串的長度懈凹,將會直接返回字符串的長度(str.length)

特點(diǎn):

1. 嚴(yán)格區(qū)分大小寫

2. 在使用indexOf檢索數(shù)組時蜀变,用‘===’去匹配悄谐,意味著會檢查數(shù)據(jù)類型

2.9 iframe有什么優(yōu)點(diǎn)、缺點(diǎn)

參考答案:

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

  1. iframe能夠原封不動的把嵌入的網(wǎng)頁展現(xiàn)出來库北。
  2. 如果有多個網(wǎng)頁引用iframe爬舰,那么你只需要修改iframe的內(nèi)容,就可以實(shí)現(xiàn)調(diào)用的每一個頁面內(nèi)容的更改寒瓦,方便快捷情屹。
  3. 網(wǎng)頁如果為了統(tǒng)一風(fēng)格,頭部和版本都是一樣的杂腰,就可以寫成一個頁面垃你,用iframe來嵌套,可以增加代碼的可重用。
  4. 如果遇到加載緩慢的第三方內(nèi)容如圖標(biāo)和廣告惜颇,這些問題可以由iframe來解決皆刺。

缺點(diǎn):

  1. iframe會阻塞主頁面的onload事件;
  2. iframe和主頁面共享連接池凌摄,而瀏覽器對相同域的連接有限制羡蛾,所以會影響頁面的并行加載。會產(chǎn)生很多頁面锨亏,不容易管理痴怨。
  3. iframe框架結(jié)構(gòu)有時會讓人感到迷惑,如果框架個數(shù)多的話器予,可能會出現(xiàn)上下浪藻、左右滾動條,會分散訪問者的注意力乾翔,用戶體驗(yàn)度差珠移。
  4. 代碼復(fù)雜,無法被一些搜索引擎索引到末融,這一點(diǎn)很關(guān)鍵钧惧,現(xiàn)在的搜索引擎爬蟲還不能很好的處理iframe中的內(nèi)容,所以使用iframe會不利于搜索引擎優(yōu)化(SEO)勾习。
  5. 很多的移動設(shè)備無法完全顯示框架浓瞪,設(shè)備兼容性差。
  6. iframe框架頁面會增加服務(wù)器的http請求巧婶,對于大型網(wǎng)站是不可取的乾颁。

2.10 webComponents

參考答案:

Web Components 總的來說是提供一整套完善的封裝機(jī)制來把 Web 組件化這個東西標(biāo)準(zhǔn)化,每個框架實(shí)現(xiàn) 的組件都統(tǒng)一標(biāo)準(zhǔn)地進(jìn)行輸入輸出艺栈,這樣可以更好推動組件的復(fù)用

包含四個部分

1. Custom Elements

2. HTML Imports

3. HTML Templates

4. Shadow DOM

Custom Elements

提供一種方式讓開發(fā)者可以自定義 HTML 元素英岭,包括特定的組成,樣式和行為湿右。支持 Web Components 標(biāo)準(zhǔn)的瀏覽器會提供一系列 API 給開發(fā)者用于創(chuàng)建自定義的元素诅妹,或者擴(kuò)展現(xiàn)有元素。

HTML Imports

一種在 HTMLs 中引用以及復(fù)用其他的 HTML 文檔的方式毅人。這個 Import 很漂亮吭狡,可以簡單理解為我們常見 的模板中的include之類的作用

HTML Templates

模板

Shadow DOM

提供一種更好地組織頁面元素的方式,來為日趨復(fù)雜的頁面應(yīng)用提供強(qiáng)大支持丈莺,避免代碼間的相互影響

2.11 dva的數(shù)據(jù)流流向是怎么樣的

參考答案:

數(shù)據(jù)的改變發(fā)生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉(zhuǎn)等)觸發(fā)的划煮,當(dāng)此類行為會改變數(shù)據(jù) 的時候可以通過dispatch發(fā)起一個 action,如果是同步行為會直接通過Reducers改變State缔俄,如果是 異步行為(副作用)會先觸發(fā)Effects然后流向Reducers最終改變State弛秋,所以在 dva 中器躏,數(shù)據(jù)流向非 常清晰簡明,并且思路基本跟開源社區(qū)保持一致蟹略。

19832495-cbfb205b14b77bdb.png

2.12 變量提升

參考答案:

JavaScript是單線程語言邀桑,所以執(zhí)行肯定是按順序執(zhí)行。但是并不是逐行的分析和執(zhí)行科乎,而是一段一段地分析執(zhí)行壁畸,會先進(jìn)行編譯階段然后才是執(zhí)行階段。在編譯階段階段茅茂,代碼真正執(zhí)行前的幾毫秒捏萍,會檢測到所有的變量和函數(shù)聲明,所有這些函數(shù)和變量聲明都被添加到名為Lexical Environment的JavaScript數(shù)據(jù)結(jié)構(gòu)內(nèi)的內(nèi)存中空闲。所以這些變量和函數(shù)能在它們真正被聲明之前使用令杈。

2.13 作用域

參考答案:

概念:作用域就是一個獨(dú)立的地盤锯岖,讓變量不會外泄叹坦、暴露出去。也就是說作用域最大的用處就是隔離變量吓肋,不同作用域下同名變量不會有沖突跌榔。

ES6 之前 JavaScript 沒有塊級作用域,只有全局作用域和函數(shù)作用域异雁。ES6 的到來,為我們提供了‘塊級作用域’,可通過新增命令 let 和 const 來體現(xiàn)僧须。

擴(kuò)展:

var ——ES5 變量聲明方式

  1. 在變量未賦值時纲刀,變量undefined(為使用聲明變量時也為undefined)
  2. 作用域——var的作用域?yàn)榉椒ㄗ饔糜颍恢灰诜椒▋?nèi)定義了担平,整個方法內(nèi)的定義變量后的代碼都可以使用

let——ES6變量聲明方式

  1. 在變量為聲明前直接使用會報錯
  2. 作用域——let為塊作用域——通常let比var 范圍要小
  3. let禁止重復(fù)聲明變量示绊,否則會報錯;var可以重復(fù)聲明

const——ES6變量聲明方式

const為常量聲明方式暂论;聲明變量時必須初始化面褐,在后面出現(xiàn)的代碼中不能再修改該常量的值

const實(shí)際上保證的,并不是變量的值不得改動取胎,而是變量指向的那個內(nèi)存地址不得改動

2.14 javascript中arguments相關(guān)的問題

參考答案:

arguments

在js中展哭,我們在調(diào)用有參數(shù)的函數(shù)時,當(dāng)往這個調(diào)用的有參函數(shù)傳參時扼菠,js會把所傳的參數(shù)全部存到一個叫arguments的對象里面摄杂。它是一個類數(shù)組數(shù)據(jù)

由來

Javascrip中每個函數(shù)都會有一個Arguments對象實(shí)例arguments,引用著函數(shù)的實(shí)參循榆。它是寄生在js函數(shù)當(dāng)中的,不能顯式創(chuàng)建墨坚,arguments對象只有函數(shù)開始時才可用

作用

有了arguments這個對象之后秧饮,我們可以不用給函數(shù)預(yù)先設(shè)定形參了映挂,可以動態(tài)地通過arguments為函數(shù)加入?yún)?shù)

2.15 編碼和字符集的區(qū)別

參考答案:

字符集是書寫系統(tǒng)字母與符號的集合,而字符編碼則是將字符映射為一特定的字節(jié)或字節(jié)序列盗尸,是一種規(guī)則柑船。通常特定的字符集采用特定的編碼方式(即一種字符集對應(yīng)一種字符編碼(例如:ASCII、IOS-8859-1泼各、GB2312鞍时、GBK,都是即表示了字符集又表示了對應(yīng)的字符編碼扣蜻,但Unicode不是逆巍,它采用現(xiàn)代的模型))

擴(kuò)展:

字符:在計算機(jī)和電信技術(shù)中,一個字符是一個單位的字形莽使、類字形單位或符號的基本信息锐极。即一個字符可以是一個中文漢字、一個英文字母芳肌、一個阿拉伯?dāng)?shù)字灵再、一個標(biāo)點(diǎn)符號等。

字符集:多個字符的集合亿笤。例如GB2312是中國國家標(biāo)準(zhǔn)的簡體中文字符集翎迁,GB2312收錄簡化漢字(6763個)及一般符號、序號净薛、數(shù)字鸳兽、拉丁字母、日文假名罕拂、希臘字母揍异、俄文字母、漢語拼音符號爆班、漢語注音字母衷掷,共 7445 個圖形字符。

字符編碼:把字符集中的字符編碼為(映射)指定集合中的某一對象(例如:比特模式柿菩、自然數(shù)序列戚嗅、電脈沖),以便文本在計算機(jī)中存儲和通過通信網(wǎng)絡(luò)的傳遞枢舶。

2.16 null 和 undefined 的區(qū)別懦胞,如何讓一個屬性變?yōu)閚ull

參考答案:

undefined 表示一個變量自然的、最原始的狀態(tài)值凉泄,而 null 則表示一個變量被人為的設(shè)置為空對象躏尉,而不是原始狀態(tài)。所以后众,在實(shí)際使用過程中胀糜,為了保證變量所代表的語義颅拦,不要對一個變量顯式的賦值 undefined,當(dāng)需要釋放一個對象時教藻,直接賦值為 null 即可距帅。

解析:

undefined 的字面意思就是:未定義的值 。這個值的語義是括堤,希望表示一個變量最原始的狀態(tài)碌秸,而非人為操作的結(jié)果 。 這種原始狀態(tài)會在以下 4 種場景中出現(xiàn):

  1. 聲明了一個變量悄窃,但沒有賦值

  2. 訪問對象上不存在的屬性

  3. 函數(shù)定義了形參讥电,但沒有傳遞實(shí)參

  4. 使用 void 對表達(dá)式求值

因此,undefined 一般都來自于某個表達(dá)式最原始的狀態(tài)值广匙,不是人為操作的結(jié)果允趟。當(dāng)然,你也可以手動給一個變量賦值 undefined鸦致,但這樣做沒有意義潮剪,因?yàn)橐粋€變量不賦值就是 undefined 。

null 的字面意思是:空值 分唾。這個值的語義是抗碰,希望表示 一個對象被人為的重置為空對象,而非一個變量最原始的狀態(tài) 绽乔。 在內(nèi)存里的表示就是弧蝇,棧中的變量沒有指向堆中的內(nèi)存對象

image

null 有屬于自己的類型 Null,而不屬于Object類型折砸,typeof 之所以會判定為 Object 類型看疗,是因?yàn)镴avaScript 數(shù)據(jù)類型在底層都是以二進(jìn)制的形式表示的,二進(jìn)制的前三位為 0 會被 typeof 判斷為對象類型睦授,而 null 的二進(jìn)制位恰好都是 0 两芳,因此,null 被誤判斷為 Object 類型去枷。

2.17 數(shù)組和偽數(shù)組的區(qū)別

參考答案

  1. 定義
  • 數(shù)組是一個特殊對象,與常規(guī)對象的區(qū)別:
    • 當(dāng)由新元素添加到列表中時怖辆,自動更新length屬性
    • 設(shè)置length屬性,可以截斷數(shù)組
    • 從Array.protoype中繼承了方法
    • 屬性為'Array'
  • 類數(shù)組是一個擁有l(wèi)ength屬性删顶,并且他屬性為非負(fù)整數(shù)的普通對象竖螃,類數(shù)組不能直接調(diào)用數(shù)組方法。
  1. 區(qū)別
    本質(zhì):類數(shù)組是簡單對象逗余,它的原型關(guān)系與數(shù)組不同特咆。
  2. 類數(shù)組轉(zhuǎn)換為數(shù)組
  • 轉(zhuǎn)換方法
    • 使用Array.from()
    • 使用Array.prototype.slice.call()
    • 使用Array.prototype.forEach()進(jìn)行屬性遍歷并組成新的數(shù)組
  • 轉(zhuǎn)換須知
    • 轉(zhuǎn)換后的數(shù)組長度由length屬性決定。索引不連續(xù)時轉(zhuǎn)換結(jié)果是連續(xù)的猎荠,會自動補(bǔ)位坚弱。

2.18 手寫一個發(fā)布訂閱

參考答案

interface CacheProps {
  [key: string]: Array<((data?: unknown) => void)>;
}

class Observer {
  private caches: CacheProps = {}; // 事件中心
  on (eventName: string, fn: (data?: unknown) => void){ // eventName事件名-獨(dú)一無二, fn訂閱后執(zhí)行的自定義行為
    this.caches[eventName] = this.caches[eventName] || [];
    this.caches[eventName].push(fn);
  }

  emit (eventName: string, data?: unknown) { // 發(fā)布 => 將訂閱的事件進(jìn)行統(tǒng)一執(zhí)行
    if (this.caches[eventName]) {
      this.caches[eventName].forEach((fn: (data?: unknown) => void) => fn(data));
    }
  }

  off (eventName: string, fn?: (data?: unknown) => void) { // 取消訂閱 => 若fn不傳, 直接取消該事件所有訂閱信息
    if (this.caches[eventName]) {
      const newCaches = fn ? this.caches[eventName].filter(e => e !== fn) : [];
      this.caches[eventName] = newCaches;
    }
  }

}  

2.19 介紹下 Set蜀备、Map关摇、WeakSet 和 WeakMap 的區(qū)別荒叶?

參考答案

Set

  1. 成員不能重復(fù);
  2. 只有鍵值输虱,沒有鍵名些楣,有點(diǎn)類似數(shù)組;
  3. 可以遍歷宪睹,方法有add愁茁、delete、has

WeakSet

  1. 成員都是對象(引用)亭病;
  2. 成員都是弱引用鹅很,隨時可以消失(不計入垃圾回收機(jī)制)∽锾可以用來保存 DOM 節(jié)點(diǎn)促煮,不容易造成內(nèi)存泄露;
  3. 不能遍歷整袁,方法有add菠齿、delete、has坐昙;

Map

  1. 本質(zhì)上是鍵值對的集合,類似集合炸客;
  2. 可以遍歷疾棵,方法很多,可以跟各種數(shù)據(jù)格式轉(zhuǎn)換痹仙;

WeakMap

  1. 只接收對象為鍵名(null 除外)是尔,不接受其他類型的值作為鍵名;
  2. 鍵名指向的對象蝶溶,不計入垃圾回收機(jī)制嗜历;
  3. 不能遍歷,方法同get抖所、set梨州、has、delete田轧;

2.20 簡單說說 js 中有哪幾種內(nèi)存泄露的情況

參考答案

  1. 意外的全局變量暴匠;
  2. 閉包;
  3. 未被清空的定時器傻粘;
  4. 未被銷毀的事件監(jiān)聽每窖;
  5. DOM 引用帮掉;

2.21 異步筆試題

請寫出下面代碼的運(yùn)行結(jié)果:

// 今日頭條面試題
async function async1() {
  console.log('async1 start')
  await async2()
  console.log('async1 end')
}
async function async2() {
  console.log('async2')
}
console.log('script start')
setTimeout(function () {
  console.log('settimeout')
})
async1()
new Promise(function (resolve) {
  console.log('promise1')
  resolve()
}).then(function () {
  console.log('promise2')
})
console.log('script end')

//題目的本質(zhì),就是考察setTimeout窒典、promise蟆炊、async await的實(shí)現(xiàn)及執(zhí)行順序,以及 JS 的事件循環(huán)的相關(guān)問題瀑志。
//答案
//script start
//async1 start
//async2
//promise1
//script end
//async1 end
//promise2
//settimeout

2.22 json和xml數(shù)據(jù)的區(qū)別

參考答案

  1. 數(shù)據(jù)體積方面:xml是重量級的涩搓,json是輕量級的,傳遞的速度更快些劈猪。
  2. 數(shù)據(jù)傳輸方面:xml在傳輸過程中比較占帶寬昧甘,json占帶寬少,易于壓縮战得。
  3. 數(shù)據(jù)交互方面:json與javascript的交互更加方便充边,更容易解析處理,更好的進(jìn)行數(shù)據(jù)交互
  4. 數(shù)據(jù)描述方面:json對數(shù)據(jù)的描述性比xml較差
  5. xml和json都用在項(xiàng)目交互下常侦,xml多用于做配置文件浇冰,json用于數(shù)據(jù)交互。

2.23 JavaScript有幾種方法判斷變量的類型?

參考答案

  1. 使用typeof檢測當(dāng)需要判斷變量是否是number, string, boolean, function, undefined等類型時刮吧,可以使用typeof進(jìn)行判斷湖饱。

  2. 使用instanceof檢測instanceof運(yùn)算符與typeof運(yùn)算符相似,用于識別正在處理的對象的類型杀捻。與typeof方法不同的是井厌,instanceof 方法要求開發(fā)者明確地確認(rèn)對象為某特定類型。

  3. 使用constructor檢測constructor本來是原型對象上的屬性致讥,指向構(gòu)造函數(shù)仅仆。但是根據(jù)實(shí)例對象尋找屬性的順序,若實(shí)例對象上沒有實(shí)例屬性或方法時垢袱,就去原型鏈上尋找墓拜,因此,實(shí)例對象也是能使用constructor屬性的请契。

2.24 代碼解釋題

參考答案

題目:

// 寫出執(zhí)行結(jié)果咳榜,并解釋原因
var min = Math.min();
max = Math.max();
console.log(min < max);
// 寫出執(zhí)行結(jié)果,并解釋原因

答案
false

解析

  • 按常規(guī)的思路爽锥,這段代碼應(yīng)該輸出 true涌韩,畢竟最小值小于最大值。但是卻輸出 false
  • MDN 相關(guān)文檔是這樣解釋的
    • Math.min 的參數(shù)是 0 個或者多個氯夷,如果多個參數(shù)很容易理解臣樱,返回參數(shù)中最小的。如果沒有參數(shù),則返回 Infinity雇毫,無窮大玄捕。
    • 而 Math.max 沒有傳遞參數(shù)時返回的是-Infinity.所以輸出 false

2.25 代碼解析題

參考答案

題目

var company = {
    address: 'beijing'
}
var yideng = Object.create(company);
delete yideng.address
console.log(yideng.address);
// 寫出執(zhí)行結(jié)果,并解釋原因

答案
beijing

解析
這里的 yideng 通過 prototype 繼承了 company的 address棚放。yideng自己并沒有address屬性枚粘。所以delete操作符的作用是無效的。

擴(kuò)展
1.delete使用原則:delete 操作符用來刪除一個對象的屬性席吴。
2.delete在刪除一個不可配置的屬性時在嚴(yán)格模式和非嚴(yán)格模式下的區(qū)別:
(1)在嚴(yán)格模式中赌结,如果屬性是一個不可配置(non-configurable)屬性捞蛋,刪除時會拋出異常;
(2)非嚴(yán)格模式下返回 false孝冒。
3.delete能刪除隱式聲明的全局變量:這個全局變量其實(shí)是global對象(window)的屬性
4.delete能刪除的:
(1)可配置對象的屬性(2)隱式聲明的全局變量 (3)用戶定義的屬性 (4)在ECMAScript 6中,通過 const 或 let 聲明指定的 "temporal dead zone" (TDZ) 對 delete 操作符也會起作用
delete不能刪除的:
(2)顯式聲明的全局變量 (2)內(nèi)置對象的內(nèi)置屬性 (3)一個對象從原型繼承而來的屬性
5.delete刪除數(shù)組元素:
(1)當(dāng)你刪除一個數(shù)組元素時拟杉,數(shù)組的 length 屬性并不會變小庄涡,數(shù)組元素變成undefined
(2)當(dāng)用 delete 操作符刪除一個數(shù)組元素時,被刪除的元素已經(jīng)完全不屬于該數(shù)組搬设。
(3)如果你想讓一個數(shù)組元素的值變?yōu)?undefined 而不是刪除它穴店,可以使用 undefined 給其賦值而不是使用 delete 操作符。此時數(shù)組元素是在數(shù)組中的
6.delete 操作符與直接釋放內(nèi)存(只能通過解除引用來間接釋放)沒有關(guān)系拿穴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泣洞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子默色,更是在濱河造成了極大的恐慌球凰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腿宰,死亡現(xiàn)場離奇詭異呕诉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吃度,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門甩挫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人椿每,你說我怎么就攤上這事伊者。” “怎么了间护?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵亦渗,是天一觀的道長。 經(jīng)常有香客問我兑牡,道長央碟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮亿虽,結(jié)果婚禮上菱涤,老公的妹妹穿的比我還像新娘。我一直安慰自己洛勉,他們只是感情好粘秆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著收毫,像睡著了一般攻走。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上此再,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天昔搂,我揣著相機(jī)與錄音,去河邊找鬼输拇。 笑死摘符,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的策吠。 我是一名探鬼主播逛裤,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼猴抹!你這毒婦竟也來了带族?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蟀给,失蹤者是張志新(化名)和其女友劉穎蝙砌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坤溃,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拍霜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了薪介。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祠饺。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汁政,靈堂內(nèi)的尸體忽然破棺而出道偷,到底是詐尸還是另有隱情,我是刑警寧澤记劈,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布勺鸦,位于F島的核電站,受9級特大地震影響目木,放射性物質(zhì)發(fā)生泄漏换途。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望军拟。 院中可真熱鬧剃执,春花似錦、人聲如沸懈息。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辫继。三九已至怒见,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姑宽,已是汗流浹背遣耍。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留低千,地道東北人配阵。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像示血,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子救拉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345