從面試官角度看一次前端面試經(jīng)歷(6 個考察點)
作者:隱冬
https://juejin.cn/post/6907146147065856013
今天被抓差給候選者進行初面。在這里記錄一下面試中涉及的幾個知識點。
每次面試我都會遞給候選者一瓶水,這樣可以讓候選者沒那么緊張,有更好的狀態(tài)進行面試,畢竟面試是雙向選擇,公司也需要盡快找到合適的人,沒那么多網(wǎng)上說的心理戰(zhàn)。
這里我還想吐槽一下面試造火箭工作擰螺絲,尤其是開發(fā)行業(yè),很多面試官針對自己擅長的方向大問特問,完全忽略了候選人的優(yōu)勢,從而給候選人帶來一個極差的面試體驗。面試最好還是要通過候選人身上的優(yōu)點來判斷對方是否適合加入你的團隊。
正常的面試應該是按照候選人簡歷中涉及的技術點發(fā)問,不然面試時給你一份簡歷干嘛,至于簡歷中未涉及的知識點有沒有必要問,我覺得沒什么必要的,因為很多人在寫簡歷的時候都是力求全面,恨不得聽說過的知識點都寫上熟悉。所以按照簡歷提問就可以了。除此之外再問一些最近流行的技術,主要考察的是候選人對新技術的敏感性和對新事物的接受能力。
如果其中涉及到候選人回答不上的問題也需要給候選人做一番解答,畢竟人家那么遠來你這面試,總要有所收獲不是。
最后在簡歷中挑選一個候選人比較擅長的點深入來問,這個環(huán)節(jié)我一般稱為定級,前面的問題如果回答的不錯,這個人基本就通過了,到最后就要給人定級。如果前面問題回答的不理想基本也到不了這個環(huán)節(jié)。
Proxy
在2020年來看Proxy早已經(jīng)不是一個陌生的詞了,他能做的是有很多,尤其在Vue3.0通過Proxy來重構之后,很多面試官喜歡問這個Proxy以及和Object.defineProperty的對比。
Proxy是專門為對象設置訪問代理器的,通過Proxy可以輕松監(jiān)視到對象的讀寫過程,相比于defineProperty,Proxy他的功能要更為強大甚至使用起來也更為方便。
這里我們定義一個person對象,我們通過new Proxy的方式來去為我們的person來創(chuàng)建一個代理對象。
Proxy構造函數(shù)的第一個參數(shù)就是我們需要代理的對象,這里是person,第二個參數(shù)也是一個對象,我們可以把這個對象稱之為代理的處理對象,這個對象中可以通過get方法來去監(jiān)視屬性的訪問,通過set方法來去介紹對象當中設置屬性這樣的一個過程。
const?person?=?{
????name:?'yd',
????age:?18
}
const?personProxy?=?new?Proxy(person,?{
????get()?{},
????set()?{}
})
先來看get方法,這個方法最簡單可以接收兩個參數(shù),第一個就是所代理的目標對象,第二個就是外部所訪問的這個屬性的屬性名。這個方法的返回值將會作為外部去訪問這個屬性得到的結(jié)果。
{
????get(target,?property)?{
????????console.log(target,?property);
????????return?property?in?target???target[property]?:?undefined;
????}
}
再來看下set方法,這個方法默認接收三個參數(shù), 分別是代理目標對象,以及我們要寫入的屬性名稱還有最后我們要寫入的屬性值。我們可以做一些校驗,比如說如果設置的是age,他的值就必須是整數(shù),否則就拋錯。
{
????set(target,?property,?value)?{
????????console.log(target,?property,?value);
????????if?(property?===?'age')?{
????????????if?(!Number.isInteger(value))?{
????????????????throw?new?TypeError(``${value}?must?be?a?integer);
????????????}
????????}
????????target[property]?=?value;
????}
}
相比于Object.defineProperty, Proxy到底有哪些優(yōu)勢。
首先最明顯的優(yōu)勢就是在于Proxy要更為強大一些,那這個強大具體體現(xiàn)在Object.defineProperty只能監(jiān)聽到對象屬性的讀取或者是寫入,而Proxy除讀寫外還可以監(jiān)聽對象中屬性的刪除,對對象當中方法的調(diào)用等等。
第二點優(yōu)勢就是對于數(shù)組對象進行監(jiān)視,通常我們想要監(jiān)視數(shù)組的變化,基本要依靠重寫數(shù)組方法,這也是Vue的實現(xiàn)方式,proxy可以直接監(jiān)視數(shù)組的變化。以往我們想要通過Object.defineProperty去監(jiān)視數(shù)組的操作最常見的方式是重寫數(shù)組的操作方法,這也是Vue.js中所使用的方式,大體的方式就是通過自定義的方法去覆蓋掉數(shù)組原型對象上的push,shift之類的方法,以此來劫持對應的方法調(diào)用的過程。
對象的鍵支持什么類型
這個問題考察的是候選人的基礎知識是否扎實。
很多人都會認為對象的鍵是字符串類型,如果在以前確實沒錯,但是ES2015版本中對象的鍵類型還可以是Symbol。
const?person?=?{
????name:?'yd',
????[Symbol()]:?18
}
這也是引出下面的Symbol。
Symbol
在ECMAScript2015之前,對象的屬性名都是字符串,而字符串是有可能會重復的。如果重復的話就會產(chǎn)生沖突。
以前解決這種問題最好的方式就是約定,但是約定的方式只是規(guī)避了問題并不是徹底解決了這個問題。如果在這個過程中有人不遵守約定那這個問題仍然會存在。
ES2015為了解決這個問題提供了一種全新的原始數(shù)據(jù)類型Symbol,翻譯過來的意思叫做符號,翻譯過來就是表示一個獨一無二的值。通過Symbol函數(shù)就可以創(chuàng)建一個Symbol類型的數(shù)據(jù),而且這種類型的數(shù)據(jù)typeof的結(jié)果就是symbol,那這也就表示他確實是一個全新的類型。
const?s?=?Symbol();
typeof?s;?//?symbol類型
這種類型最大的特點就是獨一無二,也就是說我們通過Symbol函數(shù)創(chuàng)建的每一個值都是唯一的。他永遠不會重復。
Symbol()?===?Symbol();?//?false
考慮到在開發(fā)過程中的調(diào)試Symbol創(chuàng)建時允許接收一個字符串,作為這個值的描述文本, 對于我們多次使用Symbol時就可以區(qū)分出是哪一個Symbol,但這個參數(shù)也僅是描述作用,相同的描述字段生成的值仍是不同的。
const?s1?=?Symbol('foo');
const?s2?=?Symbol('foo');
s1?===?s2;?//?false
從ES2015開始,對象就已經(jīng)允許使用Symbol作為屬性名。那也就是說現(xiàn)在對象的屬性名可以是兩種類型,字符串和Symbol。
const?person?=?{
????[Symbol()]:?123,
????[Symbol()]:?456
}
如果我們需要在全局去復用一個相同的Symbol值,我們可以使用全局變量的方式去實現(xiàn),或者是使用Symbol類型提供的一個靜態(tài)方法去實現(xiàn)。具體就是Symbol的靜態(tài)方法for,這個方法接收一個字符串作為參數(shù),相同的參數(shù)一定對應相同的值。
const?s1?=?Symbol.for('foo');
const?s2?=?Symbol.for('foo');
s1?===?s2;?//?true
這個方法維護了一個全局的注冊表,為字符串和Symbol提供了一個對應關系。需要注意的是,在內(nèi)部維護的是字符串和Symbol的關系,那也就是說如參數(shù)不是字符串,會轉(zhuǎn)換為字符串。
const?s1?=?Symbol.for('true');
const?s2?=?Symbol.for(true);
s1?===?s2;?//?true
JSONP
很多人對jsonp的理解都停留在概念上,沒有真正理解過他的原理,他為什么可以跨域,當然不僅僅是script標簽不受同源策略影響,實際上jsonp是一種前后端約定的解決方案。
不過現(xiàn)在基本已經(jīng)很少用到了。因為現(xiàn)在已經(jīng)有了更流行的CORS方案,相對來說也會更安全,不過jsonp還是有其自身的優(yōu)勢的。
很多人都知道瀏覽器的同源策略,就是發(fā)送請求的頁面地址和被請求的接口地址的域名,協(xié)議,端口三者必須一致,否則瀏覽器就會攔截這種請求。瀏覽器攔截的意思不是說請求發(fā)布出去,請求還是可以正常觸達服務器的,如果服務器正常返回了瀏覽器也會接收的到,只是不會交給我們所在的頁面。這一點查看network是可以看到的。
jsonp一般是利用script標簽的src屬性,對于服務器來說只有請求和響應兩種操作,請求來了就會響應,無論響應的是什么。請求的類型實在太多了。
瀏覽器輸入一個url是一個請求,ajax調(diào)用一個接口也是一個請求,img和script的src也是請求。這些地址都會觸達服務器。那為什么jsonp一般會選用script標簽呢,首先大家都知道script加載的js是沒有跨域限制的,因為加載的是一個腳本,不是一個ajax請求。你可以理解為瀏覽器限制的是XMLHttpRequest這個對象,而script是不使用這個對象的。
僅僅沒有限制還不夠,還有一個更重要的點因為script是執(zhí)行js腳本的標簽,他所請求到的內(nèi)容會直接當做js來執(zhí)行。
這也可以看出,jsonp和ajax對返回參數(shù)的要求是不同的,jsonp需要服務返回一段js腳本,ajax需要返回的是數(shù)據(jù)。
因此這就要求服務器單獨來處理jsonp這中請求,一般服務器接口會把響應的數(shù)據(jù)通過函數(shù)調(diào)用的方式返回,比如說返回的內(nèi)容是'yd',那就要返回成cb('yd')
cb('yd')
這是一段函數(shù)調(diào)用的腳本,通過script標簽加載之后會立即執(zhí)行的,如果我們在全局定義一個cb函數(shù)。那么這段腳本執(zhí)行的時候就會調(diào)用到我們定義的那個函數(shù),函數(shù)中的參數(shù)就是服務返回的值了。前端也就可以在這個函數(shù)中獲取到了。
function?cb?(data)?{
????console.log(data);
}
所以說jsonp是前后端共同約定的一種結(jié)果。
CORS
瀏覽器通過同源策略來限制前后端的跨域問題,但同時也給了相應的解決方案。服務器在返回相應的時候可以通過設置響應頭來允許哪些網(wǎng)址跨域請求,這樣前端就可以成功拿到響應的結(jié)果了。所以這也證實了,前端拿不到結(jié)果不是服務器不返回,而是瀏覽器沒有給到前端。
Access-Control-Allow-Origin:?www.xxxx.com
webpack的proxy是如何解決跨域的?
前面說了,跨域是因為瀏覽器的同源策略限制,問題發(fā)生在瀏覽器身上,那我們是不是可以避過瀏覽器呢。前面我寫過一篇前端需要知道的nginx,里面介紹了反向代理和負載均衡,其實這里就像是反向代理一樣。我們在使用webpack開發(fā)項目的時候,webpack的dev-server模塊會啟動一個服務器,這個服務器不止幫我們做了自動更新,同時也可以做到反向代理。就是我們把請求發(fā)送給webpack-dev-server, 然后webpack-dev-server再去請求后端服務器,服務之間的請求是沒有跨域問題的,只要后端返回了webpack-dev-server就能拿到,然后再返回給前端。好了基本上就問了這幾個問題,老板說面試時間控制在20分鐘左右。
??愛心三連擊 1.看到這里了就點個在看支持下吧,你的「點贊,在看」是我創(chuàng)作的動力。
2.關注公眾號
程序員成長指北,回復「1」加入高級前端交流群!「在這里有好多 前端?開發(fā)者,會討論?前端 Node 知識,互相學習」!3.也可添加微信【ikoala520】,一起成長。
“在看轉(zhuǎn)發(fā)”是最大的支持
