更新:謝謝你們的支持,最近折騰了一個博客官網出來,方便你們系統閱讀,後續會有更多內容和更多優化,猛戳這裏查看css
------ 如下是正文 ------html
半月刊第四期來啦,這段時間 Daily-Interview-Question 新增了 14 道高頻面試題,今天就把最近半月彙總的面試題和部分答案發給你們,幫助你們查漏補缺,歡迎 加羣 互相學習。前端
更多更全的面試題和答案彙總在下面的項目中,點擊查看。vue
項目地址:Daily-Interview-Questiongit
若是修改了,Vue 是如何監控到屬性的修改並給出警告的。github
解析:面試
if (process.env.NODE_ENV !== 'production') {
var hyphenatedKey = hyphenate(key);
if (isReservedAttribute(hyphenatedKey) ||
config.isReservedAttr(hyphenatedKey)) {
warn(
("\"" + hyphenatedKey + "\" is a reserved attribute and cannot be used as component prop."),
vm
);
}
defineReactive$$1(props, key, value, function () {
if (!isRoot && !isUpdatingChildComponent) {
warn(
"Avoid mutating a prop directly since the value will be " +
"overwritten whenever the parent component re-renders. " +
"Instead, use a data or computed property based on the prop's " +
"value. Prop being mutated: \"" + key + "\"",
vm
);
}
});
}
複製代碼
在initProps的時候,在defineReactive時經過判斷是否在開發環境,若是是開發環境,會在觸發set的時候判斷是否此key是否處於updatingChildren中被修改,若是不是,說明此修改來自子組件,觸發warning提示。vuex
須要特別注意的是,當你從子組件修改的prop屬於基礎類型時會觸發提示。 這種狀況下,你是沒法修改父組件的數據源的, 由於基礎類型賦值時是值拷貝。你直接將另外一個非基礎類型(Object, array)賦值到此key時也會觸發提示(但實際上不會影響父組件的數據源), 當你修改object的屬性時不會觸發提示,而且會修改父組件數據源的數據。segmentfault
未完待續,點擊查看更多細節:第 40 題跨域
var a = 10;
(function () {
console.log(a)
a = 5
console.log(window.a)
var a = 20;
console.log(a)
})()
複製代碼
解析:
依次輸出:undefined -> 10 -> 20
在當即執行函數中,var a = 20;
語句定義了一個局部變量 a
,因爲js的變量聲明提高機制,局部變量a
的聲明會被提高至當即執行函數的函數體最上方,且因爲這樣的提高並不包括賦值,所以第一條打印語句會打印undefined
,最後一條語句會打印20
。
因爲變量聲明提高,a = 5;
這條語句執行時,局部的變量a
已經聲明,所以它產生的效果是對局部的變量a
賦值,此時window.a
依舊是最開始賦值的10
。
未完待續,點擊查看更多細節:第 41題
好比 sleep(1000) 意味着等待1000毫秒,可從 Promise、Generator、Async/Await 等角度實現。
解析:4 種方式
//Promise
const sleep = time => {
return new Promise(resolve => setTimeout(resolve,time))
}
sleep(1000).then(()=>{
console.log(1)
})
//Generator
function* sleepGenerator(time) {
yield new Promise(function(resolve,reject){
setTimeout(resolve,time);
})
}
sleepGenerator(1000).next().value.then(()=>{console.log(1)})
//async
function sleep(time) {
return new Promise(resolve => setTimeout(resolve,time))
}
async function output() {
let out = await sleep(1000);
console.log(1);
return out;
}
output();
//ES5
function sleep(callback,time) {
if(typeof callback === 'function')
setTimeout(callback,time)
}
function output(){
console.log(1);
}
sleep(output,1000);
複製代碼
未完待續,點擊查看更多細節:第 42 題
解析:
sort
函數,能夠接收一個函數,返回值是比較兩個數的相對順序的值
UTF-16
排序的,對於字母數字 你能夠利用 ASCII
進行記憶[3, 15, 8, 29, 102, 22].sort();
// [102, 15, 22, 29, 3, 8]
複製代碼
[3, 15, 8, 29, 102, 22].sort((a,b) => {return a - b});
複製代碼
對於函數體返回
b-a
能夠類比上面的返回值進行交換位置
未完待續,點擊查看更多細節:第 43 題
解析:
開始加密通訊以前,客戶端和服務器首先必須創建鏈接和交換參數,這個過程叫作握手(handshake)。
假定客戶端叫作愛麗絲,服務器叫作鮑勃,整個握手過程能夠用下圖說明。
握手階段分紅五步。
第一步,愛麗絲給出協議版本號、一個客戶端生成的隨機數(Client random),以及客戶端支持的加密方法。
第二步,鮑勃確認雙方使用的加密方法,並給出數字證書、以及一個服務器生成的隨機數(Server random)。
第三步,愛麗絲確認數字證書有效,而後生成一個新的隨機數(Premaster secret),並使用數字證書中的公鑰,加密這個隨機數,發給鮑勃。
第四步,鮑勃使用本身的私鑰,獲取愛麗絲髮來的隨機數(即Premaster secret)。
第五步,愛麗絲和鮑勃根據約定的加密方法,使用前面的三個隨機數,生成"對話密鑰"(session key),用來加密接下來的整個對話過程。
參考:
未完待續,點擊查看更多細節:第 44 題
解析:
一、首先什麼是HTTP協議? http協議是超文本傳輸協議,位於tcp/ip四層模型中的應用層;經過請求/響應的方式在客戶端和服務器之間進行通訊;可是缺乏安全性,http協議信息傳輸是經過明文的方式傳輸,不作任何加密,至關於在網絡上裸奔;容易被中間人惡意篡改,這種行爲叫作中間人攻擊;
二、加密通訊: 爲了安全性,雙方可使用對稱加密的方式key進行信息交流,可是這種方式對稱加密祕鑰也會被攔截,也不夠安全,進而仍是存在被中間人攻擊風險; 因而人們又想出來另一種方式,使用非對稱加密的方式;使用公鑰/私鑰加解密;通訊方A發起通訊並攜帶本身的公鑰,接收方B經過公鑰來加密對稱祕鑰;而後發送給發起方A;A經過私鑰解密;雙發接下來經過對稱祕鑰來進行加密通訊;可是這種方式仍是會存在一種安全性;中間人雖然不知道發起方A的私鑰,可是能夠作到偷天換日,將攔截髮起方的公鑰key;並將本身生成的一對公/私鑰的公鑰發送給B;接收方B並不知道公鑰已經被偷偷換過;按照以前的流程,B經過公鑰加密本身生成的對稱加密祕鑰key2;發送給A; 此次通訊再次被中間人攔截,儘管後面的通訊,二者仍是用key2通訊,可是中間人已經掌握了Key2;能夠進行輕鬆的加解密;仍是存在被中間人攻擊風險;
三、解決困境:權威的證書頒發機構CA來解決;
四、https主要的思想是在http基礎上增長了ssl安全層,即以上認證過程。
未完待續,點擊查看更多細節:第 45 題
var obj = {
'2': 3,
'3': 4,
'length': 2,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
複製代碼
解析:
涉及知識點:
一組數據,由數組來存,可是若是要對這組數據進行擴展,會影響到數組原型,ArrayLike的出現則提供了一箇中間數據橋樑,ArrayLike有數組的特性, 可是對ArrayLike的擴展並不會影響到原生的數組。
push 方法有意具備通用性。該方法和 call() 或 apply() 一塊兒使用時,可應用在相似數組的對象上。push 方法根據 length 屬性來決定從哪裏開始插入給定的值。若是 length 不能被轉成一個數值,則插入的元素索引爲 0,包括 length 不存在時。當 length 不存在時,將會建立它。 惟一的原生類數組(array-like)對象是 Strings,儘管如此,它們並不適用該方法,由於字符串是不可改變的。
Array.from()、splice()、concat()等。
題分析: 這個obj中定義了兩個key值,分別爲splice和push分別對應數組原型中的splice和push方法,所以這個obj能夠調用數組中的push和splice方法,調用對象的push方法:push(1),由於此時obj中定義length爲2,因此從數組中的第二項開始插入,也就是數組的第三項(下表爲2的那一項),由於數組是從第0項開始的,這時已經定義了下標爲2和3這兩項,因此它會替換第三項也就是下標爲2的值,第一次執行push完,此時key爲2的屬性值爲1,同理:第二次執行push方法,key爲3的屬性值爲2。此時的輸出結果就是:
Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ]---->
[
2: 1,
3: 2,
length: 4,
push: ƒ push(),
splice: ƒ splice()
]
複製代碼
由於只是定義了2和3兩項,沒有定義0和1這兩項,因此前面會是empty。 若是講這道題改成:
var obj = {
'2': 3,
'3': 4,
'length': 0,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
複製代碼
此時的打印結果就是:
Object(2) [1, 2, 2: 3, 3: 4, splice: ƒ, push: ƒ]---->
[
0: 1,
1: 2,
2: 3,
3: 4,
length: 2,
push: ƒ push(),
splice: ƒ splice()
]
複製代碼
原理:此時length長度設置爲0,push方法從第0項開始插入,因此填充了第0項的empty 至於爲何對象添加了splice屬性後並無調用就會變成類數組對象這個問題,這是控制檯中 DevTools 猜想類數組的一個方式: github.com/ChromeDevTo…
未完待續,點擊查看更多細節:第 46 題
解析:
當在嚴格模式中使用 Vuex 時,在屬於 Vuex 的 state 上使用 v-model
會比較棘手:
<input v-model="obj.message">
複製代碼
假設這裏的 obj
是在計算屬性中返回的一個屬於 Vuex store 的對象,在用戶輸入時,v-model
會試圖直接修改 obj.message
。在嚴格模式中,因爲這個修改不是在 mutation 函數中執行的, 這裏會拋出一個錯誤。
用「Vuex 的思惟」去解決這個問題的方法是:給 <input>
中綁定 value,而後偵聽 input
或者 change
事件,在事件回調中調用 action:
<input :value="message" @input="updateMessage">
複製代碼
// ...
computed: {
...mapState({
message: state => state.obj.message
})
},
methods: {
updateMessage (e) {
this.$store.commit('updateMessage', e.target.value)
}
}
複製代碼
下面是 mutation 函數:
// ...
mutations: {
updateMessage (state, message) {
state.obj.message = message
}
}
複製代碼
雙向綁定的計算屬性
必須認可,這樣作比簡單地使用「v-model
+ 局部狀態」要囉嗦得多,而且也損失了一些 v-model
中頗有用的特性。另外一個方法是使用帶有 setter 的雙向綁定計算屬性:
<input v-model="message">
複製代碼
// ...
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
複製代碼
未完待續,點擊查看更多細節:第 47 題
解析:
未完待續,點擊查看更多細節:第 48 題
解析:
未完待續,點擊查看更多細節:第 49 題
例: 5 + 3 - 2,結果爲 6
解析:
Number.prototype.add = function(n) {
return this.valueOf() + n;
};
Number.prototype.minus = function(n) {
return this.valueOf() - n;
};
複製代碼
未完待續,點擊查看更多細節:第 50 題
爲何在 Vue3.0 採用了 Proxy,拋棄了 Object.defineProperty?
解析:
Object.defineProperty自己有必定的監控到數組下標變化的能力: Object.defineProperty自己是能夠監控到數組下標的變化的,可是在 Vue 中,從性能/體驗的性價比考慮,尤大大就棄用了這個特性。具體咱們能夠參考 《記一次思否問答的問題思考:Vue爲何不能檢測數組變更》這篇文章,文章底部配圖中有尤大大的嚴肅回覆截圖; 下方的討論區也很值得你們下去看一看,有對於 for / forEach / for .. in .. 幾個循環方式的討論。
關於 Vue 3.0 的其餘信息咱們能夠參考 尤大大發布的 Vue 3.0 新特性預覽PPT
直接經過數組的下標給數組設置值,不能實時響應。 爲了解決這個問題,通過vue內部處理後可使用如下幾種方法來監聽數組
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
複製代碼
因爲只針對了以上幾種方法進行了hack處理,因此其餘數組的屬性也是檢測不到的,仍是具備必定的侷限性。
Object.defineProperty只能劫持對象的屬性,所以咱們須要對每一個對象的每一個屬性進行遍歷。Vue 2.x裏,是經過 遞歸 + 遍歷 data 對象來實現對數據的監控的,若是屬性值也是對象那麼須要深度遍歷,顯然若是能劫持一個完整的對象是纔是更好的選擇。
而要取代它的Proxy有如下兩個優勢;
能夠劫持整個對象,並返回一個新對象 有13種劫持操做
未完待續,點擊查看更多細節:第 51 題
解析:
<div class="parent">
<div class="child"></div>
</div>
複製代碼
div.parent {
display: flex;
justify-content: center;
align-items: center;
}
複製代碼
div.parent {
position: relative;
}
div.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 或者 */
div.child {
width: 50px;
height: 10px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -25px;
margin-top: -5px;
}
/* 或 */
div.child {
width: 50px;
height: 10px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
複製代碼
div.parent {
display: grid;
}
div.child {
justify-self: center;
align-self: center;
}
複製代碼
div.parent {
font-size: 0;
text-align: center;
&::before {
content: "";
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
}
}
div.parent{
display: inline-block;
vertical-align: middle;
}
複製代碼
未完待續,點擊查看更多細節:第 52 題
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x)
console.log(b.x)
複製代碼
解析:
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
a.x // --> undefined
b.x // --> {n: 2}
複製代碼
答案已經寫上面了,這道題的關鍵在於
.
的優先級高於=
,因此先執行a.x
,堆內存中的{n: 1}
就會變成{n: 1, x: undefined}
,改變以後相應的b.x
也變化了,由於指向的是同一個對象。從右到左
,因此先執行a = {n: 2}
,a
的引用就被改變了,而後這個返回值又賦值給了a.x
,須要注意的是這時候a.x
是第一步中的{n: 1, x: undefined}
那個對象,其實就是b.x
,至關於b.x = {n: 2}
未完待續,點擊查看更多細節:第 53 題
進階系列文章彙總以下,以爲不錯點個 Star,歡迎 加羣 互相學習。
我是木易楊,公衆號「高級前端進階」做者,跟着我每週重點攻克一個前端面試重難點。接下來讓我帶你走進高級前端的世界,在進階的路上,共勉!