基礎(chǔ)篇
1.彈性盒子中 flex: 0 1 auto 表示什么意思
flex :flex-grow flex-shrink flex-basis
①.flex-grow 剩余空間索取
默認(rèn)值為0侨把,不索取
eg:父元素400骇笔,子元素A為100px笨触,B為200px.則剩余空間為100
此時(shí)A的flex-grow 為1寸认,B為2油宜,
則A=100px+1001/3; B=200px+1002/3
②.flex-shrink 子元素總寬度大于復(fù)制元素如何縮小
父400px,A 200px B 300px
AB總寬度超出父元素100px;
如果A不減少,則flex-shrink :0,B減少;
②,flex-basis
該屬性用來(lái)設(shè)置元素的寬度蕊苗,當(dāng)然width也可以用來(lái)設(shè)置元素的寬度沿后,如果設(shè)置了width和flex-basis,那么flex-basis會(huì)覆蓋width值朽砰。
2.求字符串?dāng)?shù)組的最長(zhǎng)公共前綴
比如輸入: ["flower","flow","flight"]尖滚,輸出: "fl"
[https://github.com/sisterAn/JavaScript-Algorithms/issues/19](https://github.com/sisterAn/JavaScript-Algorithms/issues/19)
思路:獲取數(shù)組中的最大值及最小值字符串,最小字符串與最大字符串的最長(zhǎng)公共前綴也為其他字符串的公共前綴瞧柔,即為字符串?dāng)?shù)組的最長(zhǎng)公共前綴
var longestCommonPrefix = function(strs) {
if (strs === null || strs.length === 0) return "";
if(strs.length === 1) return strs[0]
let min = 0, max = 0
for(let i = 1; i < strs.length; i++) {
if(strs[min] > strs[i]) min = i
if(strs[max] < strs[i]) max = i
}
for(let j = 0; j < strs[min].length; j++) {
if(strs[min].charAt(j) !== strs[max].charAt(j)) {
return strs[min].substring(0, j)
}
}
return strs[min]
};
3.rem與em的區(qū)別
rem是根據(jù)根的font-size變化熔掺,而em是根據(jù)父級(jí)的font-size變化
rem:相對(duì)于根元素html的font-size,假如html為font-size:12px非剃,那么置逻,在其當(dāng)中的div設(shè)置為font-size:2rem,就是當(dāng)中的div為24px
em:相對(duì)于父元素計(jì)算,假如某個(gè)p元素為font-size:12px,在它內(nèi)部有個(gè)span標(biāo)簽备绽,設(shè)置font-size:2em,那么券坞,這時(shí)候的span字體大小為:12*2=24px
4.css選擇器權(quán)重
!important -> 行內(nèi)樣式 -> #id -> .class -> 元素和偽元素 -> * -> 繼承 -> 默認(rèn)
5.CSS新特性
transition:過(guò)渡
transform:旋轉(zhuǎn)鬓催、縮放、移動(dòng)或者傾斜
animation:動(dòng)畫(huà)
gradient:漸變
shadow:陰影
border-radius:圓角
6.多行元素的文本省略號(hào)
overflow : hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical
7.數(shù)組操作
map: 遍歷數(shù)組恨锚,返回回調(diào)返回值組成的新數(shù)組
forEach: 無(wú)法break宇驾,可以用try/catch中throw new Error來(lái)停止
filter: 過(guò)濾
some: 有一項(xiàng)返回true,則整體為true
every: 有一項(xiàng)返回false猴伶,則整體為false
join: 通過(guò)指定連接符生成字符串
push / pop: 末尾推入和彈出课舍,改變?cè)瓟?shù)組, 返回推入/彈出項(xiàng)【有誤】
unshift / shift: 頭部推入和彈出他挎,改變?cè)瓟?shù)組筝尾,返回操作項(xiàng)【有誤】
sort(fn) / reverse: 排序與反轉(zhuǎn),改變?cè)瓟?shù)組
concat: 連接數(shù)組办桨,不影響原數(shù)組筹淫, 淺拷貝
slice(start, end): 返回截?cái)嗪蟮男聰?shù)組,不改變?cè)瓟?shù)組
splice(start, number, value...): 返回刪除元素組成的數(shù)組呢撞,value 為插入項(xiàng)损姜,改變?cè)瓟?shù)組
indexOf / lastIndexOf(value, fromIndex): 查找數(shù)組項(xiàng),返回對(duì)應(yīng)的下標(biāo)
reduce / reduceRight(fn(prev, cur)殊霞, defaultPrev): 兩兩執(zhí)行摧阅,prev 為上次化簡(jiǎn)函數(shù)的return值,cur 為當(dāng)前值(從第二項(xiàng)開(kāi)始)
8.閉包
什么是閉包绷蹲?
函數(shù)A 里面包含了 函數(shù)B棒卷,而 函數(shù)B 里面使用了 函數(shù)A 的變量,那么 函數(shù)B 被稱(chēng)為閉包瘸右。
又或者:閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)
function A() {
var a = 1;
function B() {
console.log(a);
}
return B();
}
閉包的特征
函數(shù)內(nèi)再嵌套函數(shù)
內(nèi)部函數(shù)可以引用外層的參數(shù)和變量
參數(shù)和變量不會(huì)被垃圾回收制回收
對(duì)閉包的理解
使用閉包主要是為了設(shè)計(jì)私有的方法和變量娇跟。閉包的優(yōu)點(diǎn)是可以避免全局變量的污染,缺點(diǎn)是閉包會(huì)常駐內(nèi)存太颤,會(huì)增大內(nèi)存使用量苞俘,使用不當(dāng)很容易造成內(nèi)存泄露。在js中龄章,函數(shù)即閉包吃谣,只有函數(shù)才會(huì)產(chǎn)生作用域的概念
閉包 的最大用處有兩個(gè),一個(gè)是可以讀取函數(shù)內(nèi)部的變量做裙,另一個(gè)就是讓這些變量始終保持在內(nèi)存中
閉包的另一個(gè)用處岗憋,是封裝對(duì)象的私有屬性和私有方法
閉包的好處
能夠?qū)崿F(xiàn)封裝和緩存等
閉包的壞處
就是消耗內(nèi)存、不正當(dāng)使用會(huì)造成內(nèi)存溢出的問(wèn)題
for(var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
輸出:3個(gè)3
解析:首先锚贱,for 循環(huán)是同步代碼仔戈,先執(zhí)行三遍 for,i 變成了 3;然后监徘,再執(zhí)行異步代碼 setTimeout晋修,這時(shí)候輸出的 i,只能是 3 個(gè) 3 了
9.原型和原型鏈
在JavaScript中凰盔,每當(dāng)定義一個(gè)函數(shù)數(shù)據(jù)類(lèi)型(普通函數(shù)墓卦、類(lèi))時(shí)候,都會(huì)天生自帶一個(gè)prototype屬性户敬,這個(gè)屬性指向函數(shù)的原型對(duì)象落剪,并且這個(gè)屬性是一個(gè)對(duì)象數(shù)據(jù)類(lèi)型的值。
在JavaScript中萬(wàn)物都是對(duì)象尿庐,對(duì)象和對(duì)象之間也有關(guān)系忠怖,并不是孤立存在的。對(duì)象之間的繼承關(guān)系屁倔,在JavaScript中是通過(guò)prototype對(duì)象指向父類(lèi)對(duì)象脑又,直到指向Object對(duì)象為止暮胧,這樣就形成了一個(gè)原型指向的鏈條锐借,專(zhuān)業(yè)術(shù)語(yǔ)稱(chēng)之為原型鏈。
10.Set往衷、Map的區(qū)別
應(yīng)用場(chǎng)景Set用于數(shù)據(jù)重組钞翔,Map用于數(shù)據(jù)儲(chǔ)存
Set:
1,成員不能重復(fù)
2席舍,只有鍵值沒(méi)有鍵名布轿,類(lèi)似數(shù)組
3,可以遍歷来颤,方法有add, delete,has
Map:
1汰扭,本質(zhì)上是健值對(duì)的集合,類(lèi)似集合
2福铅,可以遍歷萝毛,可以跟各種數(shù)據(jù)格式轉(zhuǎn)換
11.網(wǎng)頁(yè)從輸入網(wǎng)址到渲染完成經(jīng)歷了哪些過(guò)程?
大致可以分為如下7步:
- 輸入網(wǎng)址滑黔;
- 發(fā)送到DNS服務(wù)器笆包,并獲取域名對(duì)應(yīng)的web服務(wù)器對(duì)應(yīng)的ip地址;
- 與web服務(wù)器建立TCP連接略荡;
- 瀏覽器向web服務(wù)器發(fā)送http請(qǐng)求庵佣;
- web服務(wù)器響應(yīng)請(qǐng)求,并返回指定url的數(shù)據(jù)(或錯(cuò)誤信息汛兜,或重定向的新的url地址)巴粪;
- 瀏覽器下載web服務(wù)器返回的數(shù)據(jù)及解析html源文件;
- 生成DOM樹(shù),解析css和js肛根,渲染頁(yè)面衡创,直至顯示完成;
Vue.js
1. 組件通信方式有哪些晶通?
父子組件通信:
props 和 event璃氢、v-model、 .sync狮辽、 ref一也、 children
非父子組件通信:
listeners、 provide 和 inject喉脖、eventbus椰苟、通過(guò)根實(shí)例$root訪問(wèn)、vuex树叽、dispatch 和 brodcast
2.子組件為什么不可以修改父組件傳遞的Prop舆蝴?
Vue提倡單向數(shù)據(jù)流,即父級(jí) props 的更新會(huì)流向子組件,但是反過(guò)來(lái)則不行幢哨。這是為了防止意外的改變父組件狀態(tài)贤斜,使得應(yīng)用的數(shù)據(jù)流變得難以理解。如果破壞了單向數(shù)據(jù)流缕棵,當(dāng)應(yīng)用復(fù)雜時(shí)性锭,debug 的成本會(huì)非常高赠潦。
3.Vuex和單純的全局對(duì)象有什么區(qū)別?
Vuex和全局對(duì)象主要有兩大區(qū)別:
Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的草冈。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時(shí)候她奥,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會(huì)相應(yīng)地得到高效更新怎棱。
不能直接改變 store 中的狀態(tài)哩俭。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個(gè)狀態(tài)的變化拳恋,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應(yīng)用凡资。
##########4.組件中的data為什么是函數(shù)?
// data
data() {
return {
message: "子組件",
childName:this.name
}
}
// new Vue
new Vue({
el: '#app',
router,
template: '<App/>',
components: {App}
})
因?yàn)榻M件是用來(lái)復(fù)用的诅岩,JS里對(duì)象是引用關(guān)系讳苦,這樣作用域沒(méi)有隔離,而new Vue的實(shí)例吩谦,是不會(huì)被復(fù)用的鸳谜,因此不存在引用對(duì)象問(wèn)題
5.v-model 的原理
vue 項(xiàng)目中主要使用 v-model 指令在表單 input、textarea式廷、select 等元素上創(chuàng)建雙向數(shù)據(jù)綁定咐扭,我們知道 v-model 本質(zhì)上不過(guò)是語(yǔ)法糖,v-model 在內(nèi)部為不同的輸入元素使用不同的屬性并拋出不同的事件:
text 和 textarea 元素使用 value 屬性和 input 事件;
checkbox 和 radio 使用 checked 屬性和 change 事件蝗肪;
select 字段將 value 作為 prop 并將 change 作為事件;
以 input 表單元素為例:
<input v-model='something'>
相當(dāng)于
<input v-bind:value="something" v-on:input="something = $event.target.value">
7.nextTick()
在下次DOM更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)袜爪。在修改數(shù)據(jù)之后,立即使用的這個(gè)回調(diào)函數(shù)薛闪,獲取更新后的DOM
8.Vue優(yōu)化
代碼層面的優(yōu)化
v-if 和 v-show 區(qū)分使用場(chǎng)景
computed 和 watch 區(qū)分使用場(chǎng)景
v-for 遍歷必須為 item 添加 key辛馆,且避免同時(shí)使用 v-if
長(zhǎng)列表性能優(yōu)化
事件的銷(xiāo)毀
圖片資源懶加載
路由懶加載
第三方插件的按需引入
優(yōu)化無(wú)限列表性能
服務(wù)端渲染 SSR or 預(yù)渲染
Webpack 層面的優(yōu)化
Webpack 對(duì)圖片進(jìn)行壓縮
減少 ES6 轉(zhuǎn)為 ES5 的冗余代碼
提取公共代碼
模板預(yù)編譯
提取組件的 CSS
優(yōu)化 SourceMap
構(gòu)建結(jié)果輸出分析
Vue 項(xiàng)目的編譯優(yōu)化
9.MVVM
M - Model,Model 代表數(shù)據(jù)模型豁延,也可以在 Model 中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯
V - View昙篙,View 代表 UI 組件,它負(fù)責(zé)將數(shù)據(jù)模型轉(zhuǎn)化為 UI 展現(xiàn)出來(lái)
VM - ViewModel诱咏,ViewModel 監(jiān)聽(tīng)模型數(shù)據(jù)的改變和控制視圖行為苔可、處理用戶(hù)交互,簡(jiǎn)單理解就是一個(gè)同步 View 和 Model 的對(duì)象袋狞,連接 Model 和 View
10.v-for 中 key 的作用是什么焚辅?
key 是給每個(gè) vnode 指定的唯一 id,在同級(jí)的 vnode diff 過(guò)程中苟鸯,可以根據(jù) key 快速的對(duì)比同蜻,來(lái)判斷是否為相同節(jié)點(diǎn),并且利用 key 的唯一性可以生成 map 來(lái)更快的獲取相應(yīng)的節(jié)點(diǎn)倔毙。
另外指定 key 后埃仪,就不再采用“就地復(fù)用”策略了乙濒,可以保證渲染的準(zhǔn)確性陕赃。
11.
router的區(qū)別是什么?
$router為VueRouter的實(shí)例颁股,是一個(gè)全局路由對(duì)象么库,包含了路由跳轉(zhuǎn)的方法、鉤子函數(shù)等甘有。
$route 是路由信息對(duì)象||跳轉(zhuǎn)的路由對(duì)象诉儒,每一個(gè)路由都會(huì)有一個(gè)route對(duì)象,是一個(gè)局部對(duì)象亏掀,包含path,params,hash,query,fullPath,matched,name等路由信息參數(shù)忱反。
12.簡(jiǎn)單說(shuō)一下Vue2.x響應(yīng)式數(shù)據(jù)原理
Vue在初始化數(shù)據(jù)時(shí),會(huì)使用Object.defineProperty重新定義data中的所有屬性滤愕,當(dāng)頁(yè)面使用對(duì)應(yīng)屬性時(shí)温算,首先會(huì)進(jìn)行依賴(lài)收集(收集當(dāng)前組件的watcher)如果屬性發(fā)生變化會(huì)通知相關(guān)依賴(lài)進(jìn)行更新操作(發(fā)布訂閱)。
13.Vue3.x響應(yīng)式數(shù)據(jù)原理嗎间影?
Vue3.x改用Proxy替代Object.defineProperty注竿。因?yàn)镻roxy可以直接監(jiān)聽(tīng)對(duì)象和數(shù)組的變化,并且有多達(dá)13種攔截方法。并且作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化巩割。
Proxy只會(huì)代理對(duì)象的第一層裙顽,那么Vue3又是怎樣處理這個(gè)問(wèn)題的呢?
判斷當(dāng)前Reflect.get的返回值是否為Object宣谈,如果是則再通過(guò)reactive方法做代理愈犹, 這樣就實(shí)現(xiàn)了深度觀測(cè)。
監(jiān)測(cè)數(shù)組的時(shí)候可能觸發(fā)多次get/set闻丑,那么如何防止觸發(fā)多次呢甘萧?
我們可以判斷key是否為當(dāng)前被代理對(duì)象target自身屬性,也可以判斷舊值與新值是否相等梆掸,只有滿(mǎn)足以上兩個(gè)條件之一時(shí)扬卷,才有可能執(zhí)行trigger。
14.Vue模版編譯原理
簡(jiǎn)單說(shuō)酸钦,Vue的編譯過(guò)程就是將template轉(zhuǎn)化為render函數(shù)的過(guò)程怪得。會(huì)經(jīng)歷以下階段:
生成AST樹(shù)
優(yōu)化
codegen
首先解析模版,生成AST語(yǔ)法樹(shù)(一種用JavaScript對(duì)象的形式來(lái)描述整個(gè)模板)卑硫。使用大量的正則表達(dá)式對(duì)模板進(jìn)行解析徒恋,遇到標(biāo)簽、文本的時(shí)候都會(huì)執(zhí)行對(duì)應(yīng)的鉤子進(jìn)行相關(guān)處理欢伏。
Vue的數(shù)據(jù)是響應(yīng)式的入挣,但其實(shí)模板中并不是所有的數(shù)據(jù)都是響應(yīng)式的。有一些數(shù)據(jù)首次渲染后就不會(huì)再變化硝拧,對(duì)應(yīng)的DOM也不會(huì)變化径筏。那么優(yōu)化過(guò)程就是深度遍歷AST樹(shù),按照相關(guān)條件對(duì)樹(shù)節(jié)點(diǎn)進(jìn)行標(biāo)記障陶。這些被標(biāo)記的節(jié)點(diǎn)(靜態(tài)節(jié)點(diǎn))我們就可以跳過(guò)對(duì)它們的比對(duì)滋恬,對(duì)運(yùn)行時(shí)的模板起到很大的優(yōu)化作用。
編譯的最后一步是將優(yōu)化后的AST樹(shù)轉(zhuǎn)換為可執(zhí)行的代碼抱究。