1. 程式人生 > >前端面試題(附答案)

前端面試題(附答案)

最近面試遇到的一些問題,如有錯誤,歡迎指正O(∩_∩)O~~。
輸入www.baidu.com並按下回車,中間發生了什麼?
1、 瀏覽器先嚐試從Host檔案中獲取該請求對應的IP地址,如果沒有找到,就使用DNS域名解析伺服器來解析IP地址。
2、 建立TCP連線3次握手。
3、 傳送HTTP請求。
4、收到伺服器的響應,瀏覽器解析HTML文字,構建DOM樹,解析css,構建樣式樹,兩者合成render樹,最後渲染在頁面上。

webpack和gulp的區別
1、 webpack是前端資源模組的管理和打包工具,gulp是規範前端開發流程的工具。
2、webpack文件資原始檔的處理是通過入口檔案產生的依賴形成的,gulp是配置不同的task,對該task配置路徑下的所有資源都可以管理。

js的常見錯誤型別
1、 SyntaxError (語法錯誤)
eg:var 1a;
2、Reference (引用錯誤)
eg:console.log(a); var a=1;
3、TypeError(型別錯誤)
eg:var a=new 123;
4、RangeError(範圍錯誤)
eg:var a=new Array(-1); //超出有效範圍

談談你對promise的理解
promise是處理非同步操作的一種解決方案。
promise物件有三個狀態:pending、fulfilled、rejected,非同步操作的結果是由pending變成fulfilled成功或變成rejected失敗。
promise建構函式接受一個函式作為引數,以及該函式的兩個引數分別為resolve和reject兩個函式。

const promise = new Promise(function(resolve, reject){
    if(success){
        resolve(value);
    }else{
         reject(error);
    }
})

分別對應promise物件的then()和catch()方法。

promise.then(function(value){
    console.log(success);
}.catch(error){
    console.log(error);
})

Promise.all()方法用於將多個Promise例項,包裝成一個新的Promise例項。

const p=Promise.all([p1,p2,p3]);

注:a、只有p1、p2、p3的狀態都變成fulfilled,p的狀態才會變成fulfilled,此時p1、p2、p3的返回值組成一個數組,傳遞給p的回撥函式。
b、只要p1、p2、p3之中有一個變成rejected,p的狀態就會變成rejected,此時第一個變成reject的例項的返回值,會傳遞給p的回撥函式

Promise.race方法同樣是將多個 Promise 例項,包裝成一個新的 Promise 例項。

const p = Promise.race([p1, p2, p3]);

上面程式碼中,只要p1、p2、p3之中有一個例項率先改變狀態,p的狀態就跟著改變。那個率先改變的 Promise 例項的返回值,就傳遞給p的回撥函式。

promise解決了什麼問題?
promise解決了巢狀回撥的問題。
上一個函式請求的輸出作為下一個請求的輸入,如果網路延遲,下一個請求執行時,很可能上一個請求還沒返回值,這樣就會導致請求失敗。
而用promise.then()方法鏈式呼叫可以解決這個問題,當上一個then方法執行完成且成功才會呼叫下一個then。

let和const的區別?
1、var宣告的變數屬於函式作用域,let和const宣告的變數屬於塊級作用域;
2、var存在變數提升現象,而let和const不存在,會報錯。
3、var變數可以重複宣告,let和const不能重複宣告。
4、let宣告變數可以改,const宣告常量不可改,宣告變數可以改,只要保證變數的記憶體地址不改動,比如向陣列push資料、改變物件的屬性值,這些都是沒問題的。

typeof、instanceof、constructor的區別?
1、typeof 判斷運算數的資料型別,返回字串。

typeof a='number'/'string'/'function'/'object';
typeof null='object';

2、instanceof 用來判斷一個變數是否是某個物件的例項,只能用來判斷物件、陣列和函式。

[] instanceof Array    //true
[] instanceof Object    //true

3、constructor是每一個原型物件都擁有的屬性,而這個屬性也相當於是一個指標,它指向於建立當前物件的物件。

[1,2,3].constructor==Array;    //true
[1,2,3].constructor==Object;    //false

call、apply和bind的區別

fn.call(obj,1,2);           //立即執行
fn.apply(obj,[1,2]);      //立即執行
var f=fn.bind(obj,1,2);
f();        //等呼叫後再執行

js獲取url的引數值

function getRequest(){
    var url=location.search;   
    var theRequest=new Object();
    if(url.indexOf('?')!=-1){
        var  a=url.substr(1);
        var b=a.split('&');
        for(var i=0; i<b.length; i++){
			  theRequest[b[i].split('=')[0]]=b[i].split('=')[1]
		 }
    }   
    console.log(theRequest);   
}

addEventListenter第三個引數是什麼以及它的作用?
第三個引數是boolean值,true表示事件捕獲,false表示事件冒泡。

純css畫三角形

width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: red transparent transparent transparent;

淺拷貝和深拷貝的區別?
淺拷貝只是對指標的拷貝,拷貝後兩個指標指向同一個記憶體空間,修改其中任意一個物件的值,另一個物件的值也會隨之變化。
深拷貝不但對指標進行拷貝,而且對指標指向的內容進行拷貝,深拷貝新開闢了一個地址,修改其中任意一個物件的值,不會影響另一個。

重繪和重排的區別?
所有對元素視覺表現屬性的修改,都會導致重繪,比如修改了背景顏色、文字顏色、透明度等。
所有會觸發元素佈局發生變化的修改,都會導致重排,比如視窗尺寸發生變化,新增、刪除DOM元素,修改了元素盒子大小如width、height、padding等。

get和post的區別?
get後退無重新整理,post後退會重新發請求;
get能自動快取網頁,post要手動快取;
get有長度限制,不超過2048個位元組,post長度無限制;
都是TCP連線,get產生一個TCP資料包(http header和data一起傳送),post產生兩個TCP資料包(http header和data分開發送);
get向伺服器索取資料,post向伺服器提交資料。

什麼是事件委託?
事件委託是利用事件冒泡,只指定一個事件處理程式來管理某一型別的所有事件。
優點:
減少事件註冊,節省記憶體;
動態新增事件,即不用在新新增或刪除的li上繫結或解綁click事件。

移動端click事件延遲300ms的原因以及解決辦法?
當用戶點選屏幕後,瀏覽器不能立即判斷使用者是單擊還是雙擊縮放,因此會延遲300ms。
解決方案:
1、新增viewpoint meta標籤(user-scalable=no解決安卓的300ms延遲問題)

<meta name='viewport' content='width=device-width,intial-scale=1,minimum-scale=1,maxmum-scale=1,user-scalable=no'>

2、fastClick (https://github.com/ftlabs/fastclick)
移動端事件觸發順序:touchstart–>touchmove–>touchend–>click。
fastClick.js的原理是:在檢測到touchend事件的時候,會通過DOM自定義事件立即觸發模擬一個click事件,並把瀏覽器在300ms之後真正的click事件阻止掉。

說出幾個常見的狀態碼?
100:請求開始連線;
200:請求連線成功;
301:表示永久重定向,搜尋引擎會把舊地址替換成新地址,輸入www.baidu.com會跳轉至https://www.baidu.com;
302:表示臨時重定向,例如未登入的使用者會跳轉至登入頁面,搜尋引擎會保留舊地址;
304:再次重新整理網頁返回304,表示客戶端存在快取;
400:表示伺服器不理解請求的語法;
404:客戶端請求失敗,找不到該請求的連結;
500:伺服器端錯誤,比如tomcat正在啟動;

移動端開發遇到過哪些坑?
1、IOS滾動不平滑的問題 -webkit-overflow-scrolling:touch;
2、fastclick可以解決在手機上點選事件的300ms延遲;
3、統一解析度,禁止使用者縮放;

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />

4、去掉移動端點選時的高亮效果

* {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

5、 IOS中input鍵盤事件keyup、keydown、keypress支援不是很好
解決:可以用html5的oninput事件去代替keyup
6、input輸入框聚焦時底部的按鈕被彈起
解決:input聚焦時底部隱藏
7、開發App時,ios7以上頂部header和手機狀態列重合

window.uexOnload = function(type){
    var ios7style=uexWidgetOne.iOS7Style;
    var isFullScreen = uexWidgetOne.isFullScreen;
    if (ios7style == '1' && isFullScreen != '1') {
     $("body").addClass("uh_ios7");
    }
}

.uh_ios7 .uh,.uh_ios7{
    padding: 20px 0 0;
}

vue生命週期?
beforeCreate:el和data還未初始化,都為undefined;
created:完成了data資料的初始化,el沒有;
beforeMount:完成了el和data的初始化,但是el裡面的{{message}}還沒顯示出來,虛擬Dom,先把位置佔住;
mounted:el的{{message}}顯示,完成Dom元素的掛載,這個階段可以寫入ajax請求;
beforeUpdate和update:修改meaasge兩者先後呼叫;
beforeDestroy和destroy:例項銷燬後,重新改變元件裡的message,vue不再對此動作進行響應了。

angular生命週期?
ngOnChanges:當資料繫結輸入屬性(@input)的值發生變化時呼叫;
ngOninit:在第一次ngOnChanges後呼叫,只調用一次;
ngDoCheck:用於檢測和處理值的改變,可能會被多次呼叫;
ngAfterContentInit:被投影元件內容初始化之後呼叫;
ngAfterContentChecked:被投影元件內容的變更檢測之後呼叫;
ngAfterViewInit:被投影元件檢視及其子檢視初始化之後呼叫;
ngAfterViewChecked:被投影元件檢視及其子檢視的變更檢測之後呼叫;
ngOnDestroy:在Angular銷燬指令/元件之前呼叫。

vue如何實現雙向資料繫結的?
1、實現一個數據監聽器Observer,具體利用Object.defineProperty()來監聽屬性變動,如有變動可拿到最新值並通知訂閱者;
2、實現一個指令解析器Compile,對每個元素節點的指令進行掃描和解析,以及繫結相應的更新函式;
3、實現一個Watcher,作為連線Observer和Compile的橋樑,能夠訂閱並收到每個屬性變動的通知,執行指令繫結的相應函式,從而更新檢視。

angular如何實現雙向資料繫結的?
angular1:$scope綁定了n個屬性,就會新增n個watcher,當有一個watcher發生變化時,angular就發觸發$scope.$digest迴圈觸發髒檢查。
angular2:資料監聽通過zoneJs實現,zoneJs就像是一個代理,它監聽了angular所有的非同步事件(使用者輸入、點選提交等;ajax請求;setTimeout,setInterval)並重寫了所有的非同步API(猴子補丁),當非同步事件觸發時,zoneJs會通知angular有資料發生變化,需要檢測更新。

EventLoop事件迴圈機制?
Javascript的事件分兩種,巨集任務(Macrotasks)和微任務(Microtasks)。
巨集任務:setTimeout、setInterval、setImmediate;
微任務:Process.nextTick、Promise.then(注意不是new Promise);
執行順序:同步任務–>微任務–>巨集任務。

談談如何跨域?(高頻問)
同源策略:域名、埠、協議相同,其中有一個不同就會產生跨域。
1、通過使用jsonp解決跨域

<script>
    function test(json) {
        console.log('我被呼叫了');
        console.log(json);
    }
</script>
<script src="http://api.douban.com/v2/movie/top250?callback=test"></script>

如果要在jQuery中使用Ajax,則只需要在dataType屬性中把json改為jsonp即可。注意:跨域請求是隻能是get請求不能使用post請求

$.ajax({
    type: 'get',
    url: 'api/register.php',
    data:data,
    dataType: 'jsonp',
    jsonp: "callback",            //引數名
    jsonpCallback:"success",      //自定義函式名
    success:function(data){
        console.log(data);
    }
})

2、後臺配置CORS解決跨域
伺服器端檔案加上header("Access-Control-Allow-Origin", "*");
3、通過iframe來解決跨域
基於iframe實現的跨域要求兩個域具有 aa.xx.com,bb.xx.com這種主域相同的域。
http://a.study.cn/a.html 請求 http://b.study.cn/b.html
在a.html:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title>
         <script type="text/javascript">
            document.domain = 'study.cn';
            function test() {
               alert(document.getElementById('a').contentWindow);
            }
        </script>
</head>
<body>
   <iframe id='a' src='http://b.study.cn/b.html' 'test()'>
</body>
</html>

在b.html:

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title> 
 <script type="text/javascript">
      document.domain = 'study.cn';
 </script>
 </head>
 <body>
    我是b.study.cn的body
 </body>
 </html>

這樣在a頁面就能獲取b頁面的內容了。

http1.0和http2.0的區別?
https://blog.csdn.net/qq_37012533/article/details/84620865

瀏覽器的相容性問題?
https://blog.csdn.net/qq_37012533/article/details/84786135

簡單總結position定位和元素水平垂直居中(經常問)
https://blog.csdn.net/qq_37012533/article/details/84958566

MVC、MVVM的區別和聯絡?
https://blog.csdn.net/qq_37012533/article/details/84951655

談談網站效能優化?(重點問)
https://blog.csdn.net/qq_37012533/article/details/84632930