2022秋招前端面試題(二)(附答案)

UDP協(xié)議為什么不可靠?

UDP在傳輸數(shù)據(jù)之前不需要先建立連接骑丸,遠地主機的運輸層在接收到UDP報文后,不需要確認妒貌,提供不可靠交付通危。總結(jié)就以下四點:

  • 不保證消息交付:不確認灌曙,不重傳菊碟,無超時
  • 不保證交付順序:不設(shè)置包序號,不重排在刺,不會發(fā)生隊首阻塞
  • 不跟蹤連接狀態(tài):不必建立連接或重啟狀態(tài)機
  • 不進行擁塞控制:不內(nèi)置客戶端或網(wǎng)絡(luò)反饋機制

瀏覽器是如何對 HTML5 的離線儲存資源進行管理和加載逆害?

  • 在線的情況下,瀏覽器發(fā)現(xiàn) html 頭部有 manifest 屬性蚣驼,它會請求 manifest 文件魄幕,如果是第一次訪問頁面 ,那么瀏覽器就會根據(jù) manifest 文件的內(nèi)容下載相應(yīng)的資源并且進行離線存儲颖杏。如果已經(jīng)訪問過頁面并且資源已經(jīng)進行離線存儲了纯陨,那么瀏覽器就會使用離線的資源加載頁面,然后瀏覽器會對比新的 manifest 文件與舊的 manifest 文件留储,如果文件沒有發(fā)生改變翼抠,就不做任何操作,如果文件改變了获讳,就會重新下載文件中的資源并進行離線存儲阴颖。
  • 離線的情況下,瀏覽器會直接使用離線存儲的資源丐膝。

說一下類組件和函數(shù)組件的區(qū)別?

1. 語法上的區(qū)別:

函數(shù)式組件是一個純函數(shù)量愧,它是需要接受props參數(shù)并且返回一個React元素就可以了钾菊。類組件是需要繼承React.Component的,而且class組件需要創(chuàng)建render并且返回React元素侠畔,語法上來講更復(fù)雜结缚。

2. 調(diào)用方式

函數(shù)式組件可以直接調(diào)用,返回一個新的React元素软棺;類組件在調(diào)用時是需要創(chuàng)建一個實例的红竭,然后通過調(diào)用實例里的render方法來返回一個React元素。

3. 狀態(tài)管理

函數(shù)式組件沒有狀態(tài)管理喘落,類組件有狀態(tài)管理茵宪。

4. 使用場景

類組件沒有具體的要求。函數(shù)式組件一般是用在大型項目中來分割大組件(函數(shù)式組件不用創(chuàng)建實例瘦棋,所有更高效)稀火,一般情況下能用函數(shù)式組件就不用類組件,提升效率赌朋。
復(fù)制代碼

Set 和 Map有什么區(qū)別凰狞?

1、Map是鍵值對沛慢,Set是值得集合赡若,當(dāng)然鍵和值可以是任何得值
2、Map可以通過get方法獲取值团甲,而set不能因為它只有值
3逾冬、都能通過迭代器進行for...of 遍歷
4、Set的值是唯一的可以做數(shù)組去重躺苦,而Map由于沒有格式限制身腻,可以做數(shù)據(jù)存儲
復(fù)制代碼

說一說js是什么語言

JavaScript是一種直譯式腳本語言,是一種動態(tài)類型匹厘、弱類型嘀趟、基于原型的語言,內(nèi)置支持類型愈诚。它的解釋器被稱為JavaScript引擎去件,為瀏覽器的一部分,廣泛用于客戶端的腳本語言扰路,最早是在HTML(標準通用標記語言下的一個應(yīng)用)網(wǎng)頁上使用尤溜,用來給HTML網(wǎng)頁增加動態(tài)功能。

js語言是弱語言類型汗唱, 因此我們在項目開發(fā)中當(dāng)我們隨意更該某個變量的數(shù)據(jù)類型后
有可能會導(dǎo)致其他引用這個變量的方法中報錯等等宫莱。
復(fù)制代碼

說說瀏覽器緩存

緩存可以減少網(wǎng)絡(luò) IO 消耗,提高訪問速度哩罪。瀏覽器緩存是一種操作簡單授霸、效果顯著的前端性能優(yōu)化手段
很多時候巡验,大家傾向于將瀏覽器緩存簡單地理解為“HTTP 緩存”。
但事實上碘耳,瀏覽器緩存機制有四個方面显设,它們按照獲取資源時請求的優(yōu)先級依次排列如下:

Memory Cache
Service Worker Cache
HTTP Cache
Push Cache

緩存它又分為強緩存和協(xié)商緩存。優(yōu)先級較高的是強緩存辛辨,在命中強緩存失敗的情況下捕捂,才會走協(xié)商緩存
    實現(xiàn)強緩存,過去我們一直用 expires斗搞。    當(dāng)服務(wù)器返回響應(yīng)時指攒,在 Response Headers 中將過期時間寫入 expires 字段,現(xiàn)在一般使用Cache-Control 兩者同時出現(xiàn)使用Cache-Control         協(xié)商緩存僻焚,Last-Modified 是一個時間戳允悦,如果我們啟用了協(xié)商緩存,它會在首次請求時隨著 Response Headers 返回:每次請求去判斷這個時間戳是否發(fā)生變化虑啤。    從而去決定你是304讀取緩存還是給你返回最新的數(shù)據(jù)
復(fù)制代碼

原型

構(gòu)造函數(shù)是一種特殊的方法隙弛,主要用來在創(chuàng)建對象時初始化對象。每個構(gòu)造函數(shù)都有prototype(原型)(箭頭函數(shù)以及Function.prototype.bind()沒有)屬性狞山,
這個prototype(原型)屬性是一個指針全闷,指向一個對象,這個對象的用途是包含特定類型的所有實例共享的
屬性和方法铣墨,即這個原型對象是用來給實例對象共享屬性和方法的室埋。每個實例對象的__proto__都指向這個
構(gòu)造函數(shù)/類的prototype屬性办绝。

面向?qū)ο蟮娜筇匦裕豪^承/多態(tài)/封裝

關(guān)于new操作符:

1. new執(zhí)行的函數(shù), 函數(shù)內(nèi)部默認生成了一個對象

2. 函數(shù)內(nèi)部的this默認指向了這個new生成的對象

3. new執(zhí)行函數(shù)生成的這個對象, 是函數(shù)的默認返回值

ES5例子:
function Person(obj) {
    this.name = obj.name
    this.age= obj.age
}
// 原型方法
Person.prototype.say = function() {
  console.log('你好,', this.name )
}
// p為實例化對象伊约,new Person()這個操作稱為構(gòu)造函數(shù)的實例化
let p = new Person({name: '番茄', age: '27'})
console.log(p.name, p.age)
p.say()

ES6例子:
class Person{
    constructor(obj) {
      this.name = obj.name
        this.age= obj.age
  }
  say() {
      console.log(this.name)
  }
}

let p = new Person({name: 'ES6-番茄', age: '27'})
console.log(p.name, p.age)
p.say()
復(fù)制代碼

webpack配置入口出口

module.exports={
    //入口文件的配置項
    entry:{},
    //出口文件的配置項
    output:{},
    //模塊:例如解讀CSS,圖片如何轉(zhuǎn)換,壓縮
    module:{},
    //插件孕蝉,用于生產(chǎn)模版和各項功能
    plugins:[],
    //配置webpack開發(fā)服務(wù)功能
    devServer:{}
}
簡單描述了一下這幾個屬性是干什么的屡律。
描述一下npm run dev / npm run build執(zhí)行的是哪些文件
通過配置proxyTable來達到開發(fā)環(huán)境跨域的問題,然后又可以擴展和他聊聊跨域的產(chǎn)生降淮,如何跨域
最后可以在聊聊webpack的優(yōu)化超埋,例如babel-loader的優(yōu)化,gzip壓縮等等
復(fù)制代碼

說一下vue3.0你了解多少?

 <!-- 響應(yīng)式原理的改變 Vue3.x 使用Proxy取代 Vue2.x 版本的Object.defineProperty -->
 <!-- 組件選項聲明方式Vue3.x 使用Composition API setup 是Vue3.x新增的一個選項佳鳖,他
    是組件內(nèi)使用Composition API 的入口 -->
 <!-- 模板語法變化slot具名插槽語法 自定義指令 v-model 升級 -->
 <!-- 其它方面的更改Suspense支持Fragment(多個根節(jié)點) 和Protal (在dom其他部分渲染組建內(nèi)容)組件
     針對一些特殊的場景做了處理霍殴。基于treeshaking優(yōu)化系吩,提供了更多的內(nèi)置功能来庭。 -->
復(fù)制代碼

你在工作終于到那些問題,解決方法是什么

經(jīng)常遇到的問題就是Cannot read property ‘prototype’ of undefined
解決辦法通過瀏覽器報錯提示代碼定位問題穿挨,解決問題

Vue項目中遇到視圖不更新月弛,方法不執(zhí)行肴盏,埋點不觸發(fā)等問題
一般解決方案查看瀏覽器報錯,查看代碼運行到那個階段未之行結(jié)束帽衙,閱讀源碼以及相關(guān)文檔等
然后舉出來最近開發(fā)的項目中遇到的算是兩個比較大的問題菜皂。
復(fù)制代碼

說一下data為什么是一個函數(shù)而不是一個對象?

JavaScript中的對象是引用類型的數(shù)據(jù),當(dāng)多個實例引用同一個對象時厉萝,只要一個實例對這個對象進行操作恍飘,其他實例中的數(shù)據(jù)也會發(fā)生變化。而在Vue中冀泻,我們更多的是想要復(fù)用組件常侣,那就需要每個組件都有自己的數(shù)據(jù),這樣組件之間才不會相互干擾弹渔。所以組件的數(shù)據(jù)不能寫成對象的形式胳施,而是要寫成函數(shù)的形式。數(shù)據(jù)以函數(shù)返回值的形式定義肢专,這樣當(dāng)我們每次復(fù)用組件的時候舞肆,就會返回一個新的data,也就是說每個組件都有自己的私有數(shù)據(jù)空間博杖,它們各自維護自己的數(shù)據(jù)椿胯,不會干擾其他組件的正常運行。

說一下常見的git操作

git branch 查看本地所有分支
git status 查看當(dāng)前狀態(tài) 
git commit 提交 
git branch -a 查看所有的分支
git branch -r 查看遠程所有分支
git commit -am "nit" 提交并且加注釋 
git remote add origin git@192.168.1.119:ndshow
git push origin master 將文件給推到服務(wù)器上 
git remote show origin 顯示遠程庫origin里的資源 
git push origin master:develop
git push origin master:hb-dev 將本地庫與服務(wù)器上的庫進行關(guān)聯(lián) 
git checkout --track origin/dev 切換到遠程dev分支
git branch -D master develop 刪除本地庫develop
git checkout -b dev 建立一個新的本地分支dev
git merge origin/dev 將分支dev與當(dāng)前分支進行合并
git checkout dev 切換到本地dev分支
git remote show 查看遠程庫
git add .
git rm 文件名(包括路徑) 從git中刪除指定文件
git clone git://github.com/schacon/grit.git 從服務(wù)器上將代碼給拉下來
git config --list 看所有用戶
git ls-files 看已經(jīng)被提交的
git rm [file name] 刪除一個文件
git commit -a 提交當(dāng)前repos的所有的改變
git add [file name] 添加一個文件到git index
git commit -v 當(dāng)你用-v參數(shù)的時候可以看commit的差異
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add剃根,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暫存的更新
git rm a.a 移除文件(從暫存區(qū)和工作區(qū)中刪除)
git rm --cached a.a 移除文件(只從暫存區(qū)中刪除)
git commit -m "remove" 移除文件(從Git中刪除)
git rm -f a.a 強行移除修改后文件(從暫存區(qū)和工作區(qū)中刪除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 將文件給push到一個臨時空間中
git stash pop 將文件從臨時空間pop下來


webpack3和webpack4區(qū)別

1.mode

webpack增加了一個mode配置哩盲,只有兩種值development | production。對不同的環(huán)境他會啟用不同的配置狈醉。

2.CommonsChunkPlugin

CommonChunksPlugin已經(jīng)從webpack4中移除廉油。
可使用optimization.splitChunks進行模塊劃分(提取公用代碼)。
但是需要注意一個問題苗傅,默認配置只會對異步請求的模塊進行提取拆分抒线,如果要對entry進行拆分
需要設(shè)置optimization.splitChunks.chunks = 'all'。

3.webpack4使用MiniCssExtractPlugin取代ExtractTextWebpackPlugin渣慕。

4.代碼分割嘶炭。

使用動態(tài)import,而不是用system.import或者require.ensure

5.vue-loader逊桦。

使用vue-loader插件為.vue文件中的各部分使用相對應(yīng)的loader眨猎,比如css-loader等

6.UglifyJsPlugin

現(xiàn)在也不需要使用這個plugin了,只需要使用optimization.minimize為true就行强经,production mode下面自動為true

optimization.minimizer可以配置你自己的壓縮程序
復(fù)制代碼

New操作符做了什么事情?

1睡陪、首先創(chuàng)建了一個新對象
2、設(shè)置原型夕凝,將對象的原型設(shè)置為函數(shù)的prototype對象
3宝穗、讓函數(shù)的this指向這個對象户秤,執(zhí)行構(gòu)造函數(shù)的代碼(為這個新對象添加屬性)
4、判斷函數(shù)的返回值類型逮矛,如果是值類型鸡号,返回創(chuàng)建的對象。如果是引用類型须鼎,就返回這個引用類型的對象
復(fù)制代碼

JS閉包鲸伴,你了解多少?

應(yīng)該有面試官問過你:

  1. 什么是閉包晋控?
  2. 閉包有哪些實際運用場景汞窗?
  3. 閉包是如何產(chǎn)生的?
  4. 閉包產(chǎn)生的變量如何被回收赡译?

這些問題其實都可以被看作是同一個問題仲吏,那就是面試官在問你:你對JS閉包了解多少?

來總結(jié)一下我聽到過的答案蝌焚,盡量完全復(fù)原候選人面試的時候說的原話裹唆。

答案1: 就是一個function里面return了一個子函數(shù),子函數(shù)訪問了外面那個函數(shù)的變量只洒。

答案2: for循環(huán)里面可以用閉包來解決問題许帐。

for(var i = 0; i < 10; i++){
    setTimeout(()=>console.log(i),0)
}
// 控制臺輸出10遍10.
for(var i = 0; i < 10; i++){
    (function(a){
    setTimeout(()=>console.log(a),0)
    })(i)
}
 // 控制臺輸出0-9
復(fù)制代碼

答案3: 當(dāng)前作用域產(chǎn)產(chǎn)生了對父作用域的引用。

答案4: 不知道毕谴。是跟瀏覽器的垃圾回收機制有關(guān)嗎成畦?

開杠了。請問涝开,小伙伴的答案和以上的內(nèi)容有多少相似程度循帐?

其實,拿著這些問題好好想想忠寻,你就會發(fā)現(xiàn)這些問題都只是為了最終那一個問題惧浴。

閉包的底層實現(xiàn)原理

1. JS執(zhí)行上下文

我們都知道存和,我們手寫的js代碼是要經(jīng)過瀏覽器V8進行預(yù)編譯后才能真正的被執(zhí)行奕剃。例如變量提升、函數(shù)提升捐腿。舉個栗子纵朋。

// 栗子:
var d = 'abc';
function a(){
    console.log("函數(shù)a");
};
console.log(a);   // ? a(){ console.log("函數(shù)a"); }
a();              // '函數(shù)a'
var a = "變量a";  
console.log(a);   // '變量a'
a();              // a is not a function
var c = 123;

// 輸出結(jié)果及順序:
// ? a(){ console.log("函數(shù)a"); }
// '函數(shù)a'
// '變量a'
// a is not a function

// 栗子預(yù)編后相當(dāng)于:
function a(){
    console.log("函數(shù)a");
};
var d;
console.log(a);  // ? a(){ console.log("函數(shù)a"); }
a();              // '函數(shù)a'

a = "變量a";     // 此時變量a賦值,函數(shù)聲明被覆蓋

console.log(a); // "變量a"
a();         // a is not a function

復(fù)制代碼

那么問題來了茄袖。 請問是誰來執(zhí)行預(yù)編譯操作的操软?那這個誰又是在哪里進行預(yù)編譯的?

是的宪祥,你的疑惑沒有錯聂薪。js代碼運行需要一個運行環(huán)境家乘,那這個環(huán)境就是執(zhí)行上下文。 是的藏澳,js運行前的預(yù)編譯也是在這個環(huán)境中進行仁锯。

js執(zhí)行上下文分三種:

  • 全局執(zhí)行上下文: 代碼開始執(zhí)行時首先進入的環(huán)境。
  • 函數(shù)執(zhí)行上下文:函數(shù)調(diào)用時翔悠,會開始執(zhí)行函數(shù)中的代碼业崖。
  • eval執(zhí)行上下文:不建議使用,可忽略蓄愁。

那么双炕,執(zhí)行上下文的周期,分為兩個階段:

  • 創(chuàng)建階段
    • 創(chuàng)建詞法環(huán)境
    • 生成變量對象(VO)撮抓,建立作用域鏈妇斤、作用域鏈作用域鏈(重要的事說三遍)
    • 確認this指向丹拯,并綁定this
  • 執(zhí)行階段趟济。這個階段進行變量賦值,函數(shù)引用及執(zhí)行代碼咽笼。

你現(xiàn)在猜猜看顷编,預(yù)編譯是發(fā)生在什么時候?

噢剑刑,我忘記說了媳纬,其實與編譯還有另一個稱呼:執(zhí)行期上下文

預(yù)編譯發(fā)生在函數(shù)執(zhí)行之前施掏。預(yù)編譯四部曲為:

  1. 創(chuàng)建AO對象
  2. 找形參和變量聲明钮惠,將變量和形參作為AO屬性名,值為undefined
  3. 將實參和形參相統(tǒng)一
  4. 在函數(shù)體里找到函數(shù)聲明七芭,值賦予函數(shù)體素挽。最后程序輸出變量值的時候,就是從AO對象中拿狸驳。

所以预明,預(yù)編譯真正的結(jié)果是:

var AO = {
    a = function a(){console.log("函數(shù)a");};
    d = 'abc'
}
復(fù)制代碼

我們重新來。

1. 什么叫變量對象耙箍?

變量對象是 js 代碼在進入執(zhí)行上下文時撰糠,js 引擎在內(nèi)存中建立的一個對象,用來存放當(dāng)前執(zhí)行環(huán)境中的變量辩昆。

2. 變量對象(VO)的創(chuàng)建過程

變量對象的創(chuàng)建阅酪,是在執(zhí)行上下文創(chuàng)建階段,依次經(jīng)過以下三個過程:

  • 創(chuàng)建 arguments 對象。

    對于函數(shù)執(zhí)行環(huán)境术辐,首先查詢是否有傳入的實參砚尽,如果有,則會將參數(shù)名是實參值組成的鍵值對放入arguments 對象中辉词。否則尉辑,將參數(shù)名和 undefined組成的鍵值對放入 arguments 對象中。

//舉個栗子 
function bar(a, b, c) {
    console.log(arguments);  // [1, 2]
    console.log(arguments[2]); // undefined
}
bar(1,2)
復(fù)制代碼
  • 當(dāng)遇到同名的函數(shù)時较屿,后面的會覆蓋前面的隧魄。
console.log(a); // function a() {console.log('Is a ?') }
function a() {
    console.log('Is a');
}
function a() {
  console.log('Is a ?')
}

/**ps: 在執(zhí)行第一行代碼之前,函數(shù)聲明已經(jīng)創(chuàng)建完成.后面的對之前的聲明進行了覆蓋隘蝎。**/
復(fù)制代碼
  • 檢查當(dāng)前環(huán)境中的變量聲明并賦值為undefined购啄。當(dāng)遇到同名的函數(shù)聲明,為了避免函數(shù)被賦值為 undefined ,會忽略此聲明
console.log(a); // function a() {console.log('Is a ?') }
console.log(b); // undefined
function a() {
  console.log('Is a ');
}
function a() {
console.log('Is a ?');
}
var b = 'Is b';
var a = 10086;

/**這段代碼執(zhí)行一下嘱么,你會發(fā)現(xiàn) a 打印結(jié)果仍舊是一個函數(shù)狮含,而 b 則是 undefined。**/
復(fù)制代碼

根據(jù)以上三個步驟曼振,對于變量提升也就知道是怎么回事了几迄。

3. 變量對象變?yōu)榛顒訉ο?/h5>

執(zhí)行上下文的第二個階段,稱為執(zhí)行階段冰评,在此時映胁,會進行變量賦值,函數(shù)引用并執(zhí)行其他代碼甲雅,此時解孙,變量對象變?yōu)榛顒訉ο蟆?/p>

我們還是舉上面的例子:

console.log(a); // function a() {console.log('fjdsfs') }
console.log(b); // undefined
function a() {
   console.log('Is a');
}
function a() {
 console.log('Is a?');
}
var b = 'Is b';
console.log(b); // 'Is b'
var a = 10086; 
console.log(a);  // 10086
var b = 'Is b?';
console.log(b); // 'Is b?'
復(fù)制代碼

在上面的代碼中,代碼真正開始執(zhí)行是從第一行 console.log() 開始的抛人,自這之前弛姜,執(zhí)行上下文是這樣的:

// 創(chuàng)建過程
EC= {
  VO: {}; // 創(chuàng)建變量對象
  scopeChain: {}; // 作用域鏈
}
VO = {
  argument: {...}; // 當(dāng)前為全局上下文,所以這個屬性值是空的
  a: <a reference> // 函數(shù) a  的引用地址  b: undefiend  // 見上文創(chuàng)建變量對象的第三步}

復(fù)制代碼
詞法作用域(Lexical scope

這里想說明妖枚,我們在函數(shù)執(zhí)行上下文中有變量廷臼,在全局執(zhí)行上下文中有變量。JavaScript的一個復(fù)雜之處在于它如何查找變量绝页,如果在函數(shù)執(zhí)行上下文中找不到變量荠商,它將在調(diào)用上下文中尋找它,如果在它的調(diào)用上下文中沒有找到抒寂,就一直往上一級结啼,直到它在全局執(zhí)行上下文中查找為止掠剑。(如果最后找不到屈芜,它就是 undefined)。

再來舉個栗子:

 1: let top = 0; // 
 2: function createWarp() {
 3:   function add(a, b) {
 4:     let ret = a + b
 5:     return ret
 6:   }
 7:   return add
 8: }
 9: let sum = createWarp()
10: let result = sum(top, 8)
11: console.log('result:',result)


復(fù)制代碼

分析過程如下:

  • 在全局上下文中聲明變量top 并賦值為0.
  • 2 - 8行。在全局執(zhí)行上下文中聲明了一個名為 createWarp 的變量井佑,并為其分配了一個函數(shù)定義属铁。其中第3-7行描述了其函數(shù)定義,并將函數(shù)定義存儲到那個變量(createWarp)中躬翁。
  • 第9行焦蘑。我們在全局執(zhí)行上下文中聲明了一個名為 sum 的新變量,暫時盒发,值為 undefined例嘱。
  • 第9行。遇到()宁舰,表明需要執(zhí)行或調(diào)用一個函數(shù)拼卵。那么查找全局執(zhí)行上下文的內(nèi)存并查找名為 createWarp 的變量。 明顯蛮艰,已經(jīng)在步驟2中創(chuàng)建完畢腋腮。接著,調(diào)用它壤蚜。
  • 調(diào)用函數(shù)時即寡,回到第2行。創(chuàng)建一個新的createWarp執(zhí)行上下文袜刷。我們可以在 createWarp 的執(zhí)行上下文中創(chuàng)建自有變量聪富。js 引擎createWarp 的上下文添加到調(diào)用堆棧(call stack)。因為這個函數(shù)沒有參數(shù)著蟹,直接跳到它的主體部分.
  • 3 - 6 行善涨。我們有一個新的函數(shù)聲明,createWarp執(zhí)行上下文中創(chuàng)建一個變量 add草则。add 只存在于 createWarp 執(zhí)行上下文中, 其函數(shù)定義存儲在名為 add 的自有變量中钢拧。
  • 第7行,我們返回變量 add 的內(nèi)容炕横。js引擎查找一個名為 add 的變量并找到它. 第4行和第5行括號之間的內(nèi)容構(gòu)成該函數(shù)定義源内。
  • createWarp 調(diào)用完畢,createWarp 執(zhí)行上下文將被銷毀份殿。add 變量也跟著被銷毀膜钓。add 函數(shù)定義仍然存在,因為它返回并賦值給了 sum 變量卿嘲。 (ps: 這才是閉包產(chǎn)生的變量存于內(nèi)存當(dāng)中的真相
  • 接下來就是簡單的執(zhí)行過程颂斜,不再贅述。拾枣。
  • ……
  • 代碼執(zhí)行完畢沃疮,全局執(zhí)行上下文被銷毀盒让。sum 和 result 也跟著被銷毀。

小結(jié)一下

現(xiàn)在司蔬,如果再讓你回答什么是閉包邑茄,你能答出多少?

其實俊啼,大家說的都對肺缕。不管是函數(shù)返回一個函數(shù),還是產(chǎn)生了外部作用域的引用授帕,都是有道理的同木。

所以,什么是閉包跛十?

  • 解釋一下作用域鏈是如何產(chǎn)生的泉手。
  • 解釋一下js執(zhí)行上下文的創(chuàng)建、執(zhí)行過程偶器。
  • 解釋一下閉包所產(chǎn)生的變量放在哪了斩萌。
  • 最后請把以上3點結(jié)合起來說給面試官聽邀泉。

深拷貝淺拷貝

淺拷貝:淺拷貝通過ES6新特性O(shè)bject.assign()或者通過擴展運算法...來達到淺拷貝的目的匾南,淺拷貝修改
副本麻献,不會影響原數(shù)據(jù)涨醋,但缺點是淺拷貝只能拷貝第一層的數(shù)據(jù)葛假,且都是值類型數(shù)據(jù)卦羡,如果有引用型數(shù)據(jù)窟社,修改
副本會影響原數(shù)據(jù)痊末。

深拷貝:通過利用JSON.parse(JSON.stringify())來實現(xiàn)深拷貝的目的唁盏,但利用JSON拷貝也是有缺點的内狸,
當(dāng)要拷貝的數(shù)據(jù)中含有undefined/function/symbol類型是無法進行拷貝的,當(dāng)然我們想項目開發(fā)中需要
深拷貝的數(shù)據(jù)一般不會含有以上三種類型厘擂,如有需要可以自己在封裝一個函數(shù)來實現(xiàn)昆淡。
復(fù)制代碼

說一下你對盒模型的理解?

CSS3中的盒模型有以下兩種:標準盒模型、IE盒模型
盒模型都是由四個部分組成的,分別是margin刽严、border昂灵、padding和content
標準盒模型和IE盒模型的區(qū)別在于設(shè)置width和height時, 所對應(yīng)的范圍不同
1、標準盒模型的width和height屬性的范圍只包含了content
2舞萄、IE盒模型的width和height屬性的范圍包含了border眨补、padding和content
可以通過修改元素的box-sizing屬性來改變元素的盒模型;
1倒脓、box-sizing:content-box表示標準盒模型(默認值)
2撑螺、box-sizing:border-box表示IE盒模型(怪異盒模型)
復(fù)制代碼

CDN的作用

CDN一般會用來托管Web資源(包括文本、圖片和腳本等)崎弃,可供下載的資源(媒體文件甘晤、軟件含潘、文檔等),應(yīng)用程序(門戶網(wǎng)站等)安皱。使用CDN來加速這些資源的訪問调鬓。

(1)在性能方面艇炎,引入CDN的作用在于:

  • 用戶收到的內(nèi)容來自最近的數(shù)據(jù)中心酌伊,延遲更低,內(nèi)容加載更快
  • 部分資源請求分配給了CDN缀踪,減少了服務(wù)器的負載

(2)在安全方面居砖,CDN有助于防御DDoS、MITM等網(wǎng)絡(luò)攻擊:

  • 針對DDoS:通過監(jiān)控分析異常流量驴娃,限制其請求頻率
  • 針對MITM:從源服務(wù)器到 CDN 節(jié)點到 ISP(Internet Service Provider)奏候,全鏈路 HTTPS 通信

除此之外,CDN作為一種基礎(chǔ)的云服務(wù)唇敞,同樣具有資源托管蔗草、按需擴展(能夠應(yīng)對流量高峰)等方面的優(yōu)勢。

代碼輸出結(jié)果

Promise.resolve().then(() => {
  return new Error('error!!!')
}).then(res => {
  console.log("then: ", res)
}).catch(err => {
  console.log("catch: ", err)
})
復(fù)制代碼

輸出結(jié)果如下:

"then: " "Error: error!!!"
復(fù)制代碼

返回任意一個非 promise 的值都會被包裹成 promise 對象疆柔,因此這里的return new Error('error!!!')也被包裹成了return Promise.resolve(new Error('error!!!'))咒精,因此它會被then捕獲而不是catch。

Vuex有哪些基本屬性?為什么 Vuex 的 mutation 中不能做異步操作?

有五種旷档,分別是 State模叙、 Getter、Mutation 鞋屈、Action范咨、 Module
1、state => 基本數(shù)據(jù)(數(shù)據(jù)源存放地)
2厂庇、getters => 從基本數(shù)據(jù)派生出來的數(shù)據(jù)
3渠啊、mutations => 提交更改數(shù)據(jù)的方法,同步
4权旷、actions => 像一個裝飾器昭抒,包裹mutations,使之可以異步炼杖。
5灭返、modules => 模塊化Vuex

1、Vuex中所有的狀態(tài)更新的唯一途徑都是mutation坤邪,異步操作通過 Action 來提交 mutation實現(xiàn)熙含,這樣可以方便地跟蹤每一個狀態(tài)的變化,從而能夠?qū)崿F(xiàn)一些工具幫助更好地了解我們的應(yīng)用艇纺。
2怎静、每個mutation執(zhí)行完成后都會對應(yīng)到一個新的狀態(tài)變更邮弹,這樣devtools就可以打個快照存下來,然后就可以實現(xiàn) time-travel 了蚓聘。如果mutation支持異步操作腌乡,就沒有辦法知道狀態(tài)是何時更新的,無法很好的進行狀態(tài)的追蹤夜牡,給調(diào)試帶來困難与纽。
復(fù)制代碼
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市塘装,隨后出現(xiàn)的幾起案子急迂,更是在濱河造成了極大的恐慌,老刑警劉巖蹦肴,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僚碎,死亡現(xiàn)場離奇詭異,居然都是意外死亡阴幌,警方通過查閱死者的電腦和手機勺阐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矛双,“玉大人渊抽,你說我怎么就攤上這事”沉悖” “怎么了腰吟?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長徙瓶。 經(jīng)常有香客問我毛雇,道長,這世上最難降的妖魔是什么侦镇? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任灵疮,我火速辦了婚禮,結(jié)果婚禮上壳繁,老公的妹妹穿的比我還像新娘震捣。我一直安慰自己,他們只是感情好闹炉,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布蒿赢。 她就那樣靜靜地躺著,像睡著了一般渣触。 火紅的嫁衣襯著肌膚如雪羡棵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天嗅钻,我揣著相機與錄音皂冰,去河邊找鬼店展。 笑死,一個胖子當(dāng)著我的面吹牛秃流,可吹牛的內(nèi)容都是我干的赂蕴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舶胀,長吁一口氣:“原來是場噩夢啊……” “哼概说!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起峻贮,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤席怪,失蹤者是張志新(化名)和其女友劉穎应闯,沒想到半個月后纤控,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡碉纺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年船万,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骨田。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡耿导,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出态贤,到底是詐尸還是另有隱情舱呻,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布悠汽,位于F島的核電站箱吕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柿冲。R本人自食惡果不足惜茬高,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望假抄。 院中可真熱鬧怎栽,春花似錦、人聲如沸宿饱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谬以。三九已至强饮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛉签,已是汗流浹背胡陪。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工沥寥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柠座。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓邑雅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妈经。 傳聞我的和親對象是個殘疾皇子淮野,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容