2021前端高级面试题_2021前端面试题目100及最佳答案(新华社评出2021年国内十大新闻)
一、簡單頁面
1、CSS選擇器樣式優(yōu)先級
2、CSS實現(xiàn)三列布局(左右固定寬度,中間自適應(yīng))
(1)CSS浮動
第一個float:left,第二個float:right,第三個設(shè)置margin-left和margin-right
(2)絕對定位法
第一個定位到left,第二個定位到right,第三個設(shè)置margin-left和margin-right
(3)flex布局
.left{
width:200px;
或者
flex:0 0 200px;
}
.right{
width:200px;
或者
flex:0 0 200px;
}
.center{
flex:1;
}
3、如果要做優(yōu)化,CSS提高性能的方法有哪些?
內(nèi)聯(lián)首屏關(guān)鍵CSS
異步加載CSS
資源壓縮
合理使用選擇器
減少使用昂貴的屬性
不要使用@import
二、js
1、防抖和節(jié)流,應(yīng)用場景
防抖和節(jié)流都是防止某一時間頻繁觸發(fā),但是原理卻不一樣。
防抖是將多次執(zhí)行變?yōu)橹粓?zhí)行一次,節(jié)流是將多次執(zhí)行變?yōu)槊扛粢欢螘r間執(zhí)行。
防抖(debounce):
search搜索聯(lián)想,用戶在不斷輸入值時,用防抖來節(jié)約請求資源。
window觸發(fā)resize的時候,不斷的調(diào)整瀏覽器窗口大小會不斷的觸發(fā)這個事件,用防抖來讓其只觸發(fā)一次
節(jié)流(throttle):
鼠標(biāo)不斷點擊觸發(fā),mousedown(單位時間內(nèi)只觸發(fā)一次)
監(jiān)聽滾動事件,比如是否滑到底部自動加載更多,用throttle來判斷
2、什么是閉包
「函數(shù)」和「函數(shù)內(nèi)部能訪問到的變量」(也叫環(huán)境)的總和,就是一個閉包。
3、繼承有哪些方法
原型鏈繼承
借用構(gòu)造函數(shù)繼承(偽造對象、經(jīng)典繼承)
實例繼承(原型式繼承)
組合式繼承
寄生組合繼承
es6繼承 extends
4、什么是深/淺拷貝,有哪些實現(xiàn)方式
基本數(shù)據(jù)類型:string、number、boolean、undefined、null
引用數(shù)據(jù)類型:object、array、function
JS數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,基本數(shù)據(jù)類型保存的是值,引用類型保存的是引用地址(this指針)。淺拷貝共用一個引用地址,深拷貝會創(chuàng)建新的內(nèi)存地址。
Object.assign:對象的合并 (第一級屬性深拷貝,第一級以下的級別屬性淺拷貝。)
ES6中的 Object.assign(),第一個參數(shù)必須是個空對象。
Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標(biāo)對象,然后返回目標(biāo)對象。
let obj1 = {
a: { b: 1},
c: 2
}
let obj2 = Object.assign({},obj1)
obj2.a.b = 3; //第二層,obj1變了,是淺拷貝
obj2.c = 3; //第一層,obj1不變,是深拷貝
console.log(obj1);
console.log(obj2);
5、數(shù)組有哪些常用方法,引出下一個問題,slice和splice區(qū)別:
1.splice改變原數(shù)組,slice不改變原數(shù)組。2.splice除了可以刪除之外,還可以插入。3.splice可傳入3個參數(shù),slice接受2個參數(shù)。
6、Promise.all和Promise.race的區(qū)別,應(yīng)用場景
Promise.all()可以將多個實例組裝個成一個新實例,成功的時候返回一個成功的數(shù)組;失敗的時候則返回最先被reject失敗狀態(tài)的值。
適用場景:比如當(dāng)一個頁面需要在很多個模塊的數(shù)據(jù)都返回回來時才正常顯示,否則loading。
promise.all中的子任務(wù)是并發(fā)執(zhí)行的,適用于前后沒有依賴關(guān)系的。Promise.race()意為賽跑的意思,也就是數(shù)組中的任務(wù)哪個獲取的塊,就返回哪個,不管結(jié)果本身是成功還是失敗。一般用于和定時器綁定,比如將一個請求和三秒的定時器包裝成Promise實例,加入到Promise隊列中,請求三秒中還沒有回應(yīng)時,給用戶一些提示或相應(yīng)的操作。
7、微任務(wù)和宏任務(wù)的區(qū)別
1.宏任務(wù):當(dāng)前調(diào)用棧中執(zhí)行的代碼成為宏任務(wù)。(主代碼快,定時器等等)。
2.微任務(wù): 當(dāng)前(此次事件循環(huán)中)宏任務(wù)執(zhí)行完,在下一個宏任務(wù)開始之前需要執(zhí)行的任務(wù),可以理解為回調(diào)事件。(promise.then,proness.nextTick等等)。
3. 宏任務(wù)中的事件放在callback queue中,由事件觸發(fā)線程維護(hù);微任務(wù)的事件放在微任務(wù)隊列中,由js引擎線程維護(hù)。
微任務(wù):process.nextTick、MutationObserver、Promise.then catch finally
宏任務(wù):I/O、setTimeout、setInterval、setImmediate、requestAnimationFrame
1、Vue中的的通信方式有幾種?隔代組件的通信你用那種方式解決?
props/$emit 適用父子組件通信
ref與parent/children適用父子組件通信
attrs/listeners,provide/inject 適用于隔代組件通信
vuex,EventBus(事件總線) 適用于父子、隔代、兄弟組件通信
slot插槽方式
2、v-show 和 v-if指令的共同點和不同點?
v-show是css切換,v-if是完整的銷毀和重新創(chuàng)建,如果頻繁切換時用v-show,運行時較少改變用v-if
3、為什么使用key?
做一個唯一標(biāo)識, Diff 算法就可以正確的識別此節(jié)點。作用主要是為了高效的更新虛擬 DOM。
4、簡述computed和watch的使用場景
computed:
不支持緩存,數(shù)據(jù)變,直接會觸發(fā)相應(yīng)的操作;
watch支持異步;
監(jiān)聽的函數(shù)接收兩個參數(shù),第一個參數(shù)是最新的值;第二個參數(shù)是輸入之前的值;
當(dāng)一個屬性發(fā)生變化時,需要執(zhí)行對應(yīng)的操作;一對多;
監(jiān)聽的是這個屬性自身的變化,且不會操作緩存
監(jiān)聽數(shù)據(jù)必須是data中聲明過或者父組件傳遞過來的props中的數(shù)據(jù),當(dāng)數(shù)據(jù)變化時,觸發(fā)其他操作,函數(shù)有兩個參數(shù),
是一個計算屬性,類似于過濾器,對綁定到view的數(shù)據(jù)進(jìn)行處理
當(dāng)一個屬性受多個屬性影響的時候就需要用到computed
最典型的例子: 購物車商品結(jié)算的時候
watch:
1.是觀察的動作,
2.應(yīng)用:監(jiān)聽props,$emit或本組件的值執(zhí)行異步操作
3.無緩存性,頁面重新渲染時值不變化也會執(zhí)行
watch是一個觀察的動作
當(dāng)一條數(shù)據(jù)影響多條數(shù)據(jù)的時候就需要用watch
例子:搜索數(shù)據(jù)
5、params和query的區(qū)別(怎么定義 vue-router 的動態(tài)路由? 怎么獲取傳過來的值?)
6、$route 和 $router 的區(qū)別
8、vue-router 有哪幾種導(dǎo)航鉤子?
1.全局導(dǎo)航鉤子:router.beforeEach(to,from,next)作用:跳轉(zhuǎn)前進(jìn)行判斷攔截、組件內(nèi)的鉤子、單獨路由獨享組件
2、路由獨享鉤子可以在路由配置上直接定義 beforeEnter
3、組件內(nèi)的導(dǎo)航鉤子有三種:
beforeRouteEnter 在進(jìn)入當(dāng)前組件對應(yīng)的路由前調(diào)用
beforeRouteUpdate 在當(dāng)前路由改變,但是該組件被復(fù)用時調(diào)用
beforeRouteLeave 在離開當(dāng)前組件對應(yīng)的路由前調(diào)用=
9、Vue實例的生命周期講一下, mounted階段真實DOM存在了嘛?
Vue實例從創(chuàng)建到銷毀的過程,就是生命周期。
也就是:開始創(chuàng)建->初始化數(shù)據(jù)->編譯模板->掛載dom->數(shù)據(jù)更新重新渲染虛擬 dom->最后銷毀。這一系列的過程就是vue的生命周期。所以在mounted階段真實的DOM就已經(jīng)存在了。
beforeCreate:vue實例的掛載元素el和數(shù)據(jù)對象data都還沒有進(jìn)行初始化,還是一個 undefined狀態(tài)
created: 此時vue實例的數(shù)據(jù)對象data已經(jīng)有了,可以訪問里面的數(shù)據(jù)和方法, el還沒有,也沒有掛載dom
beforeMount: 在這里vue實例的元素el和數(shù)據(jù)對象都有了,只不過在掛載之前還是虛擬的dom節(jié)點
mounted: vue實例已經(jīng)掛在到真實的dom上,可以通過對 dom操作來獲取dom節(jié)點
beforeUpdate: 響應(yīng)式數(shù)據(jù)更新時調(diào)用,發(fā)生在虛擬dom打補(bǔ)丁之前,適合在更新之前訪問現(xiàn)有的 dom,比如手動移除已添加的事件監(jiān)聽器
updated: 虛擬dom重新渲染和打補(bǔ)丁之后調(diào)用,組成新的 dom已經(jīng)更新,避免在這個鉤子函數(shù)中操作數(shù)據(jù),防止死循環(huán)。
beforeDestroy: vue實例在銷毀前調(diào)用,在這里還可以使用,通過this也能訪問到實例,可以在這里對一些不用的定時器進(jìn)行清除,解綁事件。
destroyed:vue實例銷毀后調(diào)用,調(diào)用后所有事件監(jiān)聽器會被移除,所有的子實例都會被銷毀。
11、vuex有哪幾種屬性,怎么使用?哪種功能場景使用它?
vuex是一個專門為vue.js開發(fā)的狀態(tài)管理模式,每一個vuex應(yīng)用核心就是store(倉庫)。store基本上就是一個容器,它包含著你的應(yīng)用中大部分的state(狀態(tài))
vuex的狀態(tài)存儲是響應(yīng)式的,當(dāng) vue組件中store中讀取狀態(tài)時候,若store中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會相應(yīng)地得到高效更新。
改變store中的狀態(tài)的唯一途徑就是顯示 commit(提交)mutation,這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化。
State: 定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu),可以在這里設(shè)置默認(rèn)的初始狀態(tài)
Getter: 允許組件從Stroe中獲取數(shù)據(jù), mapGetters輔助函數(shù)僅僅是將store中的getter映射到計算屬性。
Mutation: 唯一更改store中狀態(tài)的方法,且必須是同步函數(shù)。
Action: 用于提交muatation, 而不是直接變更狀態(tài),可以包含任意異步操作。
Module: modules,可以讓每一個模塊擁有自己的state、mutation、action、getters,使得結(jié)構(gòu)非常清晰,方便管理;如果所有的狀態(tài)或者方法都寫在一個store里面,將會變得非常臃腫,難以維護(hù)。
12、vuex中state存儲的數(shù)據(jù)如果頁面刷新此時數(shù)據(jù)還會有嗎?(刷新之后銷毀了)
13、v-bind和v-model的區(qū)別, v-model原理知道嗎?
//語法糖寫法
<input type="text" v-model="name" >
//還原為以下實例
<input type="text"
v-bind:value="name"
v-on:input="name=$event.target.value">
v-bind用來綁定數(shù)據(jù)和屬性以及表達(dá)式
v-model使用在表單中,實現(xiàn)雙向數(shù)據(jù)綁定的。
14、Vue中的常見指令有那些?
v-text/v-html/v-for/v-show/v-if/v-else/v-cloak/v-bind/v-on/v-model/v-slot…
15.改變this指向call、apply與bind區(qū)別:
前兩個可以自動執(zhí)行,bind不會自動執(zhí)行,需要手動調(diào)用
call、bind與apply區(qū)別:前兩個都有無數(shù)個參數(shù),apply只有兩個參數(shù),而且第二個參數(shù)為數(shù)組
16,vue路由的兩種模式
1.hash模式
特點:在url地址上有#號
實現(xiàn)的原理:原生的hasChange事件來實現(xiàn),來監(jiān)聽hash值的變化
window.onhaschange=function(){}
刷新頁面的時候:不會去發(fā)送請求,頁面不會有任何問題,不需要后端來配合
2.history模式
特點:在url地址上沒有#號,比較與hash模式看起來好看一些
實現(xiàn)的原理:利用的是history的api 來實現(xiàn)的 popState() 來實現(xiàn)的
刷新頁面的時候:會去發(fā)送請求然后會導(dǎo)致頁面出現(xiàn)找不到的情況,需要后端來配合解決
17,vue的響應(yīng)式原理:
vue實現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過 Object.defineProperty() 數(shù)據(jù)劫持,來劫持各個屬性的setter,getter,在數(shù)據(jù)更新時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)監(jiān)聽回調(diào)。
當(dāng)把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty() 將它們轉(zhuǎn)為 getter/setter。用戶看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監(jiān)聽自己的model的數(shù)據(jù)變化,通過Compile來解析編譯模板指令(vue中是用來解析 {
{}}),
最終利用watcher搭起observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 —>視圖更新;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果。
18.Flex容器屬性
1.flex-direction主軸方向(row(默認(rèn)值):主軸為水平方向,起點在左端。row-reverse:主軸為水平方向,起點在右端。
column:主軸為垂直方向,起點在上沿。)
2.flex-wrap(nowrap(默認(rèn)值):不換行。
wrap:換行。
wrap-reverse:換行,第一行在下方。 )
3.flex-flow(12簡寫形式)
4.justify-content項目在主軸上的對齊方式。(flex-start(默認(rèn)值):左對齊(即上面頁面展示效果)
flex-end:右對齊
center: 居中
space-between:兩端對齊,項目之間的間隔都相等。
space-around:每個項目兩側(cè)的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。)
5.align-items項目在交叉軸上如何對齊。(lex-start:交叉軸的起點對齊。
flex-end:交叉軸的終點對齊。
center:交叉軸的中點對齊。
baseline: 項目的第一行文字的基線對齊。
stretch(默認(rèn)值):如果項目未設(shè)置高度或設(shè)為auto,將占滿整個容器的高度。)
6.align-content
19.標(biāo)準(zhǔn)盒模型和怪異盒模型的區(qū)別:
怪異盒模型的寬度變小
標(biāo)準(zhǔn)盒大小計算公式:width(content) + padding + border + margin
怪異盒大小的計算公式:width(content + padding + border) + margin
20.vue的插槽(slot)主要分三種:
默認(rèn)插槽,具名插槽,作用域插槽
vue中的插槽,指的是子組件中提供給父組件使用的一個占位符;
用標(biāo)簽表示,父組件可以在這個占位符中填充任何模板代碼,比如HTML、組件等,填充的內(nèi)容會替換掉子組件的標(biāo)簽(替換占位符)。
21.vue數(shù)據(jù)的雙向綁定
“vue數(shù)據(jù)的雙向綁定是通過數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式來實現(xiàn)的。其核心就是通過Object.defineProperty()方法設(shè)置set和get函數(shù)來實現(xiàn)數(shù)據(jù)的劫持,在數(shù)據(jù)變化時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。也就是說數(shù)據(jù)和視圖同步,數(shù)據(jù)發(fā)生變化,視圖跟著變化,視圖變化,數(shù)據(jù)也隨之發(fā)生改變;”
22.常用的git命令
git config
用法:git config –global user.name “[name]”
用法:git config –global user.email “”
git init
用法:git init [repository name]
該命令可用于創(chuàng)建一個新的代碼庫
git clone
用法:git clone [url]
該命令可用于通過指定的URL獲取一個代碼庫。
git add 添加文件到倉庫
git status 查看倉庫當(dāng)前的狀態(tài),顯示有變更的文件。
git diff 比較文件的不同,即暫存區(qū)和工作區(qū)的差異。
git commit 提交暫存區(qū)到本地倉庫。
git reset 回退版本。
git push
用法:git push [variable name] master
該命令可以將主分支上提交的變更發(fā)送到遠(yuǎn)程代碼庫。
23.數(shù)組和字符串的相互轉(zhuǎn)換
使用字符串的 split() 方法可以根據(jù)指定的分隔符把字符串切分為數(shù)組。
如果使用數(shù)組的 join() 方法,可以把數(shù)組元素連接為字符串。
24.js 判斷數(shù)據(jù)類型的幾種方法
typeof str // "string" 字符串
typeof num // "number" 數(shù)值
typeof array // "object" 對象(可以和函數(shù)區(qū)別開)
// ?注意,數(shù)組也是一個對象
typeof date // "object" 對象
typeof func // "function" 函數(shù)
typeof symbol // "symbol"
25.toString 方法
把對象直接轉(zhuǎn)換成字符串
26.es6新特性:
1、let 和 const
let 表示申明變量。const 表示申明常量
常量定義了就不能改了。對象除外,因為對象指向的地址沒變。
const在申明是必須被賦值。
兩者都為塊級作用域。
2、模板字符串
3、解構(gòu)
4、函數(shù)的默認(rèn)值
5、Spread / Rest 操作符,三個點…
6、箭頭函數(shù)
7、for of
for of遍歷的是鍵值對中的值
for in遍歷的是鍵值對中的鍵
8、class類,原型鏈的語法糖表現(xiàn)形式
9、導(dǎo)入導(dǎo)出
導(dǎo)入improt
導(dǎo)出export default
10、promise
Promise 用于更優(yōu)雅地處理異步請求。
11、async/await
比promise更好的解決了回調(diào)地獄
12、Symbol,新的基本類型
13、Set集合
存儲任何類型的唯一值,即集合中所保存的元素是不重復(fù)的。類數(shù)組結(jié)構(gòu)。
let arrNew = new Set(待去重的數(shù)組)
27.webpack
1、webpack的作用是什么,談?wù)勀銓λ睦斫猓?現(xiàn)在的前端網(wǎng)頁功能豐富,特別是SPA(single page web application 單頁應(yīng)用)技術(shù)流行后,JavaScript的復(fù)雜度增加和需要一大堆依賴包,還需要解決Scss,Less……新增樣式的擴(kuò)展寫法的編譯工作。
所以現(xiàn)代化的前端已經(jīng)完全依賴于webpack的輔助了。
現(xiàn)在最流行的三個前端框架,可以說和webpack已經(jīng)緊密相連,框架官方都推出了和自身框架依賴的webpack構(gòu)建工具。
react.js+WebPack
vue.js+WebPack
AngluarJS+WebPack
2、webpack的工作原理?
WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Sass,TypeScript等),并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用。在3.0出現(xiàn)后,Webpack還肩負(fù)起了優(yōu)化項目的責(zé)任。
3、webpack打包原理
把一切都視為模塊:不管是 css、JS、Image 還是 html 都可以互相引用,通過定義 entry.js,對所有依賴的文件進(jìn)行跟蹤,將各個模塊通過 loader 和 plugins 處理,然后打包在一起。
按需加載:打包過程中 Webpack 通過 Code Splitting 功能將文件分為多個 chunks,還可以將重復(fù)的部分單獨提取出來作為 commonChunk,從而實現(xiàn)按需加載。把所有依賴打包成一個 bundle.js 文件,通過代碼分割成單元片段并按需加載
4、webpack的核心概念
Entry:入口,Webpack 執(zhí)行構(gòu)建的第一步將從 Entry 開始,可抽象成輸入。告訴webpack要使用哪個模塊作為構(gòu)建項目的起點,默認(rèn)為./src/index.js
output :出口,告訴webpack在哪里輸出它打包好的代碼以及如何命名,默認(rèn)為./dist
Module:模塊,在 Webpack 里一切皆模塊,一個模塊對應(yīng)著一個文件。Webpack 會從配置的 Entry 開始遞歸找出所有依賴的模塊。
Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用于代碼合并與分割。
Loader:模塊轉(zhuǎn)換器,用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新內(nèi)容。
Plugin:擴(kuò)展插件,在 Webpack 構(gòu)建流程中的特定時機(jī)會廣播出對應(yīng)的事件,插件可以監(jiān)聽這些事件的發(fā)生,在特定時機(jī)做對應(yīng)的事情。
5、Webpack的基本功能有哪些?
代碼轉(zhuǎn)換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等等
文件優(yōu)化:壓縮 JavaScript、CSS、html 代碼,壓縮合并圖片等
代碼分割:提取多個頁面的公共代碼、提取首屏不需要執(zhí)行部分的代碼讓其異步加載
模塊合并:在采用模塊化的項目有很多模塊和文件,需要構(gòu)建功能把模塊分類合并成一個文件
自動刷新:監(jiān)聽本地源代碼的變化,自動構(gòu)建,刷新瀏覽器
代碼校驗:在代碼被提交到倉庫前需要檢測代碼是否符合規(guī)范,以及單元測試是否通過
自動發(fā)布:更新完代碼后,自動構(gòu)建出線上發(fā)布代碼并傳輸給發(fā)布系統(tǒng)。
6、gulp/grunt 與 webpack的區(qū)別是什么?
三者都是前端構(gòu)建工具,grunt和gulp在早期比較流行,現(xiàn)在webpack相對來說比較主流,不過一些輕量化的任務(wù)還是會用gulp來處理,比如單獨打包CSS文件等。grunt和gulp是基于任務(wù)和流(Task、Stream)的。
類似jQuery,找到一個(或一類)文件,對其做一系列鏈?zhǔn)讲僮鳎铝魃系臄?shù)據(jù), 整條鏈?zhǔn)讲僮鳂?gòu)成了一個任務(wù),多個任務(wù)就構(gòu)成了整個web的構(gòu)建流程。webpack是基于入口的。
webpack會自動地遞歸解析入口所需要加載的所有資源文件,然后用不同的Loader來處理不同的文件,用Plugin來擴(kuò)展webpack功能。
7、webpack是解決什么問題而生的?
如果像以前開發(fā)時一個html文件可能會引用十幾個js文件,而且順序還不能亂,因為它們存在依賴關(guān)系,同時對于ES6+等新的語法,less, sass等CSS預(yù)處理都不能很好的解決……,此時就需要一個處理這些問題的工具。
28.MVVM模式
1、MVVM相比較于MVP,將Presenter變成ViewModel,ViewModel可以理解成是View的數(shù)據(jù)模型和Presenter的合體
2、MVVM中的數(shù)據(jù)可以實現(xiàn)雙向綁定,即View層數(shù)據(jù)變化則ViewModel中的數(shù)據(jù)也隨之變化,反之ViewModel中的數(shù)據(jù)變化,則View層數(shù)據(jù)也隨之變化`
注:MVC指的是Model-View-Controller,分別代表著模型層、視圖層、控制器。
29.原型鏈
當(dāng)js試圖得到一個對象的屬性時,會先去這個對象的本身去尋找,如果這個對象本身沒有找到這個屬性,那么js就會去它構(gòu)造函數(shù)的’prototype’屬性中去尋找,也就是去’proto‘中尋找,如果’prototype’屬性本身中依舊沒有找到,’prototype’中依舊有一個‘proto’。
原型可以解決什么問題:
對象共享屬性和方法
誰有原型:
函數(shù)擁有:prototype
對象擁有:proto
對象查找屬性或者方法的順序:
先在對象本身查找–>構(gòu)造函數(shù)中查找–>對象的原型中查找–>構(gòu)造函數(shù)的原型中查找–>當(dāng)前原型中查找
原型鏈的最頂端是null
30.閉包
閉包就是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)
MDN 上面這么說:閉包是一種特殊的對象。
閉包的作用域鏈包含著它自己的作用域,以及包含它的函數(shù)的作用域和全局作用域。閉包的注意事項
通常,函數(shù)的作用域及其所有變量都會在函數(shù)執(zhí)行結(jié)束后被銷毀。但是,在創(chuàng)建了一個閉包以后,這個函數(shù)的作用域就會一直保存到閉包不存在為止。
我們首先知道閉包有3個特性:
①函數(shù)嵌套函數(shù)
②函數(shù)內(nèi)部可以引用函數(shù)外部的參數(shù)和變量
③參數(shù)和變量不會被垃圾回收機(jī)制回收
優(yōu)點:
①保護(hù)函數(shù)內(nèi)的變量安全 ,實現(xiàn)封裝,防止變量流入其他環(huán)境發(fā)生命名沖突
②在內(nèi)存中維持一個變量,可以做緩存(但使用多了同時也是一項缺點,消耗內(nèi)存)
③匿名自執(zhí)行函數(shù)可以減少內(nèi)存消耗
閉包的缺點就是常駐內(nèi)存會增大內(nèi)存使用量,并且使用不當(dāng)很容易造成內(nèi)存泄露。
如果不是因為某些特殊任務(wù)而需要閉包,在沒有必要的情況下,在其它函數(shù)中創(chuàng)建函數(shù)是不明智的,因為閉包對腳本性能具有負(fù)面影響,包括處理速度和內(nèi)存消耗。
31.Vue和React的區(qū)別是什么?
一、核心思想不同
Vue是一個靈活易用的漸進(jìn)式雙向綁定的MVVM框架。
React的核心思想是聲明式渲染和組件化、單向數(shù)據(jù)流,React既不屬于MVC也不屬于MVVM架構(gòu)。
注:React的單向數(shù)據(jù)流指的是數(shù)據(jù)主要從父節(jié)點通過props傳遞到子節(jié)點,
如果頂層某個props改變了,React會重新渲染所有的子節(jié)點,但是單向數(shù)據(jù)流并非單向綁定,
React想要從一個組件去更新另一個組件的狀態(tài),需要進(jìn)行狀態(tài)提升,即將狀態(tài)提升到他們最近的
祖先組件中,觸發(fā)父組件的狀態(tài)變更,從而影響另一個組件的顯示。單向數(shù)據(jù)流的好處是能夠保證
狀態(tài)改變的可追溯性,假如,父組件維護(hù)了一個狀態(tài),子組件如果能夠隨意更改父組件的狀態(tài),那
么各組件的狀態(tài)改變就會變得難以追溯
二、組件寫法上不同
Vue的組件寫法是通過template的單文件組件格式。
React的組件寫法是JSX+inline style,也就是吧HTML和CSS全部寫進(jìn)JavaScript中。
三、Diff算法不同
Diff算法是一種對比算法,主要是對比舊的虛擬DOM和新的虛擬DOM,找出發(fā)生更改的節(jié)點,并只
更新這些接地那,而不更新未發(fā)生變化的節(jié)點,從而準(zhǔn)確的更新DOM,減少操作真實DOM的次數(shù),
提高性能。
vue對比節(jié)點,如果節(jié)點元素類型相同,但是className不同,認(rèn)為是不同類型的元素,會進(jìn)行刪
除重建,但是react則會認(rèn)為是同類型的節(jié)點,只會修改節(jié)點屬性。
vue的列表比對采用的是首尾指針法,而react采用的是從左到右依次比對的方式,當(dāng)一個集合只
是把最后一個節(jié)點移動到了第一個,react會把前面的節(jié)點依次移動,而vue只會把最后一個節(jié)點
移動到最后一個,從這點上來說vue的對比方式更加高效。
四、響應(yīng)式原理不同
React的響應(yīng)式原理
React主要是通過setState()方法來更新狀態(tài),狀態(tài)更新之后,組件也會重新渲染。
Vue的響應(yīng)式原理
vue會遍歷data數(shù)據(jù)對象,使用Object.definedProperty()將每個屬性都轉(zhuǎn)換為getter和
setter,每個Vue組件實例都有一個對應(yīng)的watcher實例,在組件初次渲染的時候會記錄組件用到
了那些數(shù)據(jù),當(dāng)數(shù)據(jù)發(fā)生改變的時候,會觸發(fā)setter方法,并通知所有依賴這個數(shù)據(jù)的watcher實
例調(diào)用update方法去觸發(fā)組件的compile渲染方法,進(jìn)行渲染數(shù)據(jù)。
32. rem的特點:
1、rem的大小是根據(jù)html根目錄下的字體大小進(jìn)行計算的。
2、當(dāng)我們改變根目錄下的字體大小的時候,下面字體都改變。
3、rem不僅可以設(shè)置字體的大小,也可以設(shè)置元素寬、高等屬性。
33.http請求過程
瀏覽器發(fā)起請求-> 解析域名得到ip進(jìn)行TCP連接 ->瀏覽器發(fā)送HTTP請求和頭信息發(fā)送->服務(wù)器對瀏覽器進(jìn)行應(yīng)答,響應(yīng)頭信息和瀏覽器所需的內(nèi)容-> 關(guān)閉TCP連接或保持-> 瀏覽器得到數(shù)據(jù)數(shù)據(jù)進(jìn)行操作。
34.前端如何實現(xiàn)跨域?
當(dāng)一個請求 url 的協(xié)議、域名、端口三者之間任意一個與當(dāng)前頁面 url 不同即為跨域
出于瀏覽器的同源策略限制。
同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。
1.JSONP原理
利用script元素的這個開放策略,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的 JSON 數(shù)據(jù)。
但是JSONP請求一定需要對方的服務(wù)器做支持才可以。
JSONP優(yōu)點是兼容性好,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。
缺點是僅支持get方法具有局限性。
2.CORS原理
實現(xiàn)CORS通信的關(guān)鍵是服務(wù)器,需要在服務(wù)器端做一些小小的改造。
只要服務(wù)器實現(xiàn)了CORS接口,就可以跨源通信。
在響應(yīng)頭上添加Access-Control-Allow-Origin屬性,指定同源策略的地址。同源策略默認(rèn)地址是網(wǎng)頁的本身。只要瀏覽器檢測到響應(yīng)頭帶上了CORS,并且允許的源包括了本網(wǎng)站,那么就不會攔截請求響應(yīng)。
3.Nginx
瀏覽器在訪問受限時,可通過不受限的代理服務(wù)器訪問目標(biāo)站點。
proxy代理是前端用的最多的解決跨域的方法。
即配置一臺和瀏覽器相同端口的服務(wù)器,瀏覽器訪問代理服務(wù)器,代理服務(wù)器向目標(biāo)服務(wù)器發(fā)送請求,由于服務(wù)器之間不存在跨域問題,代理服務(wù)器就可以拿到請求數(shù)據(jù),而后因為瀏覽器和代理服務(wù)器端口號一致,不存在跨域問題,因此瀏覽器不會攔截從代理服務(wù)器收到的數(shù)據(jù),順利拿到請求數(shù)據(jù)。
例如:瀏覽器端口號8080,目標(biāo)服務(wù)器端口號5000,在vue中配置代理服務(wù)器來訪問目標(biāo)服務(wù)器
// vue.config.js中配置代理
devServer:{
proxy:"http://localhost:5000"
}
// 使用代理
axios.get('http://localhost:8080/students').then(
response => {
console.log('請求成功了',response.data)
},
error => {
console.log('請求失敗了',error.message)
}
)
35.vue 中的 keep-alive
keep-alive 是 vue 中的內(nèi)置組件,能夠在組件切換過程中將狀態(tài)保留在內(nèi)存中,防止重復(fù)的渲染 DOM;
keep-alive 包裹動態(tài)組件時,會緩存不活動的組件實例,而不是銷毀它們;
設(shè)置了 keep-alive 緩存的組件,會多出兩個生命周期鉤子(activated 和 deactivated )
36.vue.nextTick()方法
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM。
使用:
this.$nextTick(function(){
console.log(that.$refs.aa.innerText); //輸出:修改后的值
})
什么時候需要用的Vue.nextTick()?
1、Vue生命周期的created()鉤子函數(shù)進(jìn)行的DOM操作一定要放在Vue.nextTick()的回調(diào)函數(shù)中,原因是在created()鉤子函數(shù)執(zhí)行的時候DOM 其實并未進(jìn)行任何渲染,而此時進(jìn)行DOM操作無異于徒勞,所以此處一定要將DOM操作的js代碼放進(jìn)Vue.nextTick()的回調(diào)函數(shù)中。與之對應(yīng)的就是mounted鉤子函數(shù),因為該鉤子函數(shù)執(zhí)行時所有的DOM掛載已完成。
2.vue改變dom元素結(jié)構(gòu)后使用vue.$nextTick()方法來實現(xiàn)dom數(shù)據(jù)更新后延遲執(zhí)行后續(xù)代碼
二、em的特點:
1、字體大小是根據(jù)父元素字體大小設(shè)置的。
四、綜合
1、前端工程化理解(模塊化、組件化、規(guī)范化、自動化)
JS的模塊化、css的模塊化、資源的模塊化
從UI拆分下來的每個包含模板(HTML)+樣式(CSS)+邏輯(JS)功能完備的結(jié)構(gòu)單元
HTML規(guī)范、CSS規(guī)范、JS規(guī)范、圖片規(guī)范、命名規(guī)范
圖標(biāo)合并、持續(xù)集成、自動化構(gòu)建、自動化部署、自動化測試
2、組件封裝過程
建立組件的模板,先把架子搭起來,寫寫樣式,考慮好組件的基本邏輯。
準(zhǔn)備好組件的數(shù)據(jù)輸入。即分析好邏輯,定好 props 里面的數(shù)據(jù)、類型。
準(zhǔn)備好組件的數(shù)據(jù)輸出。即根據(jù)組件邏輯,做好要暴露出來的方法。
封裝完畢了,直接調(diào)用即可。
五、擴(kuò)展
1、Typescript中的內(nèi)置類型 Number String Boolean Null Void Undefined
2、TS的接口是什么意思
接口是在我們的應(yīng)用程序中充當(dāng)契約的結(jié)構(gòu)。它定義了要遵循的類的語法,這意味著實現(xiàn)接口的類必須實現(xiàn)它的所有成員。它不能被實例化,但是可以被實現(xiàn)它的類對象引用。無論對象是否具有特定的結(jié)構(gòu),TypeScript編譯器都使用接口進(jìn)行類型檢查
4、nodejs搭建一個簡單的http服務(wù)器過程
5、Typescript中的類的特征(繼承、封裝、多態(tài)性、抽象)
總結(jié)
以上是生活随笔為你收集整理的2021前端高级面试题_2021前端面试题目100及最佳答案(新华社评出2021年国内十大新闻)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聊一下质量管理体系中的DQE/SQE/P
- 下一篇: 【精选】uboot/linux/qt/b