前端面試題整理

一條小白澤發表於2021-01-03

css

calc, support, media各自的含義及用法?

@support主要是用於檢測瀏覽器是否支援CSS的某個屬性,其實就是條件判斷,如果支援某個屬性,你可以寫一套樣式,如果不支援某個屬性,你也可以提供另外一套樣式作為替補。

calc() 函式用於動態計算長度值。 calc()函式支援 “+”, “-”, “*”, “/” 運算;

@media 查詢,你可以針對不同的媒體型別定義不同的樣式。

css水平、垂直居中的寫法,請至少寫出4種?

這題考查的是css的基礎知識是否全面,所以平時一定要注意多積累

水平居中

  • 行內元素: text-align: center
  • 塊級元素: margin: 0 auto
  • position:absolute +left:50%+ transform:translateX(-50%)
  • display:flex + justify-content: center

垂直居中

  • 設定line-height 等於height
  • position:absolute +top:50%+ transform:translateY(-50%)
  • display:flex + align-items: center
  • display:table+display:table-cell + vertical-align: middle;

1rem、1em、1vh、1px各自代表的含義?

rem

rem是全部的長度都相對於根元素元素。通常做法是給html元素設定一個字型大小,然後其他元素的長度單位就為rem。

em

  • 子元素字型大小的em是相對於父元素字型大小
  • 元素的width/height/padding/margin用em的話是相對於該元素的font-size

vw/vh

全稱是 Viewport Width 和 Viewport Height,視窗的寬度和高度,相當於 螢幕寬度和高度的 1%,不過,處理寬度的時候%單位更合適,處理高度的 話 vh 單位更好。

px

px畫素(Pixel)。相對長度單位。畫素px是相對於顯示器螢幕解析度而言的。

一般電腦的解析度有{1920*1024}等不同的解析度

1920*1024 前者是螢幕寬度總共有1920個畫素,後者則是高度為1024個畫素

畫一條0.5px的直線?

考查的是css3的transform

height: 1px;
transform: scale(0.5);

說一下盒模型?

盒模型是css中重要的基礎知識,也是必考的基礎知識

盒模型的組成,由裡向外content,padding,border,margin.

在IE盒子模型中,width表示content+padding+border這三個部分的寬度

在標準的盒子模型中,width指content部分的寬度

box-sizing的使用

  box-sizing: content-box 是W3C盒子模型
  box-sizing: border-box 是IE盒子模型

box-sizing的預設屬性是content-box

畫一個三角形?

這屬於簡單的css考查,平時在用元件庫的同時,也別忘了原生的css

 .a{
            width: 0;
            height: 0;
            border-width: 100px;
            border-style: solid;
            border-color: transparent #0099CC transparent transparent;
            transform: rotate(90deg); /*順時針旋轉90°*/
 }

<div class="a"></div>

清除浮動的幾種方式,及原理?

清除浮動簡單,但這題要引出的是BFC,BFC也是必考的基礎知識點

  • ::after / <br> / clear: both
  • 建立父級 BFC(overflow:hidden)
  • 父級設定高度

BFC (塊級格式化上下文,是一個獨立的渲染區域,讓處於 BFC 內部的元素與外部的元素相互隔離,使內外元素的定位不會相互影響。

觸發條件:

  • 根元素
  • position: absolute/fixed
  • display: inline-block / table
  • float 元素
  • ovevflow !== visible

規則:

  • 屬於同一個 BFC 的兩個相鄰 Box 垂直排列
  • 屬於同一個 BFC 的兩個相鄰 Boxmargin 會發生重疊
  • BFC 的區域不會與 float 的元素區域重疊
  • 計算 BFC 的高度時,浮動子元素也參與計算
  • 文字層不會被浮動層覆蓋,環繞於周圍

html

說一下

label標籤主要是方便滑鼠點選使用,擴大可點選的範圍,增強使用者操作體驗

遍歷A節點的父節點下的所有子節點

這題考查原生的js操作dom,屬於非常簡單的基礎題,但長時間使用mvvm框架,可能會忘記

<script>
    var b=document.getElementById("a").parentNode.children;
    console.log(b)
</script>

js

用js遞迴的方式寫1到100求和?

遞迴我們經常用到,vue在實現雙向繫結進行資料檢驗的時候用的也是遞迴,但要我們面試的時候手寫一個遞迴,如果對遞迴的概念理解不透徹,可能還是會有一些問題。

function add(num1,num2){
	var num = num1+num2;
        if(num2+1>100){
	 return num;
	}else{
	  return add(num,num2+1)
        }
 }
var sum =add(1,2);                 

頁面渲染html的過程?

不需要死記硬背,理解整個過程即可

瀏覽器渲染頁面的一般過程:

1.瀏覽器解析html原始碼,然後建立一個 DOM樹。並行請求 css/image/js在DOM樹中,每一個HTML標籤都有一個對應的節點,並且每一個文字也都會有一個對應的文字節點。DOM樹的根節點就是 documentElement,對應的是html標籤。

2.瀏覽器解析CSS程式碼,計算出最終的樣式資料。構建CSSOM樹。對CSS程式碼中非法的語法它會直接忽略掉。解析CSS的時候會按照如下順序來定義優先順序:瀏覽器預設設定 < 使用者設定 < 外鏈樣式 < 內聯樣式 < html中的style。

3.DOM Tree + CSSOM --> 渲染樹(rendering tree)。渲染樹和DOM樹有點像,但是是有區別的。

DOM樹完全和html標籤一一對應,但是渲染樹會忽略掉不需要渲染的元素,比如head、display:none的元素等。而且一大段文字中的每一個行在渲染樹中都是獨立的一個節點。渲染樹中的每一個節點都儲存有對應的css屬性。

4.一旦渲染樹建立好了,瀏覽器就可以根據渲染樹直接把頁面繪製到螢幕上。

以上四個步驟並不是一次性順序完成的。如果DOM或者CSSOM被修改,以上過程會被重複執行。實際上,CSS和JavaScript往往會多次修改DOM或者CSSOM。

說一下CORS?

CORS是一種新標準,支援同源通訊,也支援跨域通訊。fetch是實現CORS通訊的

如何中斷ajax請求?

一種是設定超時時間讓ajax自動斷開,另一種是手動停止ajax請求,其核心是呼叫XML物件的abort方法,ajax.abort()

說一下事件代理?

事件委託是指將事件繫結到目標元素的父元素上,利用冒泡機制觸發該事件

ulEl.addEventListener('click', function(e){
    var target = event.target || event.srcElement;
    if(!!target && target.nodeName.toUpperCase() === "LI"){
        console.log(target.innerHTML);
    }
}, false);

target、currentTarget的區別?

currentTarget當前所繫結事件的元素

target當前被點選的元素

說一下巨集任務和微任務?

  1. 巨集任務:當前呼叫棧中執行的任務稱為巨集任務。(主程式碼快,定時器等等)。
  2. 微任務: 當前(此次事件迴圈中)巨集任務執行完,在下一個巨集任務開始之前需要執行的任務為微任務。(可以理解為回撥事件,promise.then,proness.nextTick等等)。
  3. 巨集任務中的事件放在callback queue中,由事件觸發執行緒維護;微任務的事件放在微任務佇列中,由js引擎執行緒維護。

說一下繼承的幾種方式及優缺點?

說比較經典的幾種繼承方式並比較優缺點就可以了

  1. 借用建構函式繼承,使用call或apply方法,將父物件的建構函式繫結在子物件上
  2. 原型繼承,將子物件的prototype指向父物件的一個例項
  3. 組合繼承

原型鏈繼承的缺點

  • 字面量重寫原型會中斷關係,使用引用型別的原型,並且子型別還無法給超型別傳遞引數。

借用建構函式(類式繼承)

  • 借用建構函式雖然解決了剛才兩種問題,但沒有原型,則複用無從談起。

組合式繼承

  • 組合式繼承是比較常用的一種繼承方法,其背後的思路是使用原型鏈實現對原型屬性和方法的繼承,而通過借用建構函式來實現對例項屬性的繼承。這樣,既通過在原型上定義方法實現了函式複用,又保證每個例項都有它自己的屬性。

說一下閉包?

閉包的實質是因為函式巢狀而形成的作用域鏈

閉包的定義即:函式 A 內部有一個函式 B,函式 B 可以訪問到函式 A 中的變數,那麼函式 B 就是閉包

export和export default的區別?

使用上的不同

export default  xxx
import xxx from './'

export xxx
import {xxx} from './'

說一下自己常用的es6的功能?

此題是一道開放題,可以自由回答。但要注意像let這種簡單的用法就別說了,說一些經常用到並有一定高度的新功能

像module、class、promise等,儘量講的詳細一點。

什麼是會話cookie,什麼是持久cookie?

cookie是伺服器返回的,指定了expire time(有效期)的是持久cookie,沒有指定的是會話cookie

陣列去重?

此題看著簡單,但要想面試官給你高分還是有難度的。至少也要寫出幾種方法

js

var arr=['12','32','89','12','12','78','12','32'];
    // 最簡單陣列去重法
    function unique1(array){
        var n = []; //一個新的臨時陣列
        for(var i = 0; i < array.length; i++){ //遍歷當前陣列
            if (n.indexOf(array[i]) == -1)
                n.push(array[i]);
        }
        return n;
    }
    arr=unique1(arr);
    // 速度最快, 佔空間最多(空間換時間)
    function unique2(array){
        var n = {}, r = [], type;
        for (var i = 0; i < array.length; i++) {
            type = typeof array[i];
            if (!n[array[i]]) {
                n[array[i]] = [type];
                r.push(array[i]);
            } else if (n[array[i]].indexOf(type) < 0) {
                n[array[i]].push(type);
                r.push(array[i]);
            }
        }
        return r;
    }
    //陣列下標判斷法
    function unique3(array){
        var n = [array[0]]; //結果陣列
        for(var i = 1; i < array.length; i++) { //從第二項開始遍歷
            if (array.indexOf(array[i]) == i) 
                n.push(array[i]);
        }
        return n;
    }

es6

es6方法陣列去重
arr=[...new Set(arr)];
es6方法陣列去重,第二種方法
function dedupe(array) {
  return Array.from(new Set(array));       //Array.from()能把set結構轉換為陣列
}

get、post的區別

此題比較簡單,但一定要回答的全面

1.get傳參方式是通過位址列URL傳遞,是可以直接看到get傳遞的引數,post傳參方式引數URL不可見,get把請求的資料在URL後通過?連線,通過&進行引數分割。psot將引數存放在HTTP的包體內

2.get傳遞資料是通過URL進行傳遞,對傳遞的資料長度是受到URL大小的限制,URL最大長度是2048個字元。post沒有長度限制

3.get後退不會有影響,post後退會重新進行提交

4.get請求可以被快取,post不可以被快取

5.get請求只URL編碼,post支援多種編碼方式

6.get請求的記錄會留在歷史記錄中,post請求不會留在歷史記錄

7.get只支援ASCII字元,post沒有字元型別限制

你所知道的http的響應碼及含義?

此題有過開發經驗的都知道幾個,但還是那句話,一定要回答的詳細且全面。

1xx(臨時響應)

100: 請求者應當繼續提出請求。

101(切換協議) 請求者已要求伺服器切換協議,伺服器已確認並準備進行切換。

2xx(成功)

200:正確的請求返回正確的結果

201:表示資源被正確的建立。比如說,我們 POST 使用者名稱、密碼正確建立了一個使用者就可以返回 201。

202:請求是正確的,但是結果正在處理中,這時候客戶端可以通過輪詢等機制繼續請求。

3xx(已重定向)

300:請求成功,但結果有多種選擇。

301:請求成功,但是資源被永久轉移。

303:使用 GET 來訪問新的地址來獲取資源。

304:請求的資源並沒有被修改過

4xx(請求錯誤)

400:請求出現錯誤,比如請求頭不對等。

401:沒有提供認證資訊。請求的時候沒有帶上 Token 等。

402:為以後需要所保留的狀態碼。

403:請求的資源不允許訪問。就是說沒有許可權。

404:請求的內容不存在。

5xx(伺服器錯誤)

500:伺服器錯誤。

501:請求還沒有被實現。

原型鏈的解釋

餓了麼面試的時候問到了,用友也問到了。沒答好,GG.
這裡寫圖片描述

基本的資料型別

5個簡單資料型別(基本資料型別)+ 1個複雜資料型別
undefiend, number string null boolean + object
ES6 新增Symbol

對前端路由的理解?前後端路由的區別?

前端的路由和後端的路由在實現技術上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現之前,前端的路由都是通過 hash 來實現的,hash 能相容低版本的瀏覽器。

http://10.0.0.1/
http://10.0.0.1/#/about
http://10.0.0.1/#/concat
123

服務端路由:每跳轉到不同的URL,都是重新訪問服務端,然後服務端返回頁面,頁面也可以是服務端獲取資料,然後和模板組合,返回HTML,也可以是直接返回模板HTML,然後由前端JS再去請求資料,使用前端模板和資料進行組合,生成想要的HTML。

前端路由:每跳轉到不同的URL都是使用前端的錨點路由,實際上只是JS根據URL來操作DOM元素,根據每個頁面需要的去服務端請求資料,返回資料後和模板進行組合,當然模板有可能是請求服務端返回的,這就是 SPA 單頁程式。

什麼是SPA

介紹下WebPakc

Promise

解釋一下call函式和apply函式的作用,以及用法

改變this的指向。
this的指向問題,在你不知道的js這本書中(神書)做了四點歸納:
1.預設繫結 (指 直接呼叫 foo(), this指向window)
2.隱式繫結(obj.foo(), this指向obj 這裡會出現很多坑,下面的問題應該會有解答)
3.顯示繫結(利用call、apply、bind改變this)
4.new(var cat = new Animal() , this指向cat物件)

前端面試題300道

1、手寫jsonp的實現

參考自: http://www.qdfuns.com/notes/16738/1b6ad6125747d28592a53a960b44c6f4.html

先說說JSONP是怎麼產生的:

其實網上關於JSONP的講解有很多,但卻千篇一律,而且雲裡霧裡,對於很多剛接觸的人來講理解起來有些困難,著用自己的方式來闡釋一下這個問題,看看是否有幫助。

1、一個眾所周知的問題,Ajax直接請求普通檔案存在跨域無許可權訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不準。

2、不過我們又發現,Web頁面上呼叫js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有"src"這個屬性的標籤都擁有跨域的能力,比如script、img、iframe)。

3、於是可以判斷,當前階段如果想通過純web端(ActiveX控制元件、服務端代理、屬於未來的HTML5之Websocket等方式不算)跨域訪問資料就只有一種可能,那就是在遠端伺服器上設法把資料裝進js格式的檔案裡,供客戶端呼叫和進一步處理。

4、恰巧我們已經知道有一種叫做JSON的純字元資料格式可以簡潔的描述複雜資料,更妙的是JSON還被js原生支援,所以在客戶端幾乎可以隨心所欲的處理這種格式的資料。

5、這樣子解決方案就呼之欲出了,web客戶端通過與呼叫指令碼一模一樣的方式,來呼叫跨域伺服器上動態生成的js格式檔案(一般以JSON為字尾),顯而易見,伺服器之所以要動態生成JSON檔案,目的就在於把客戶端需要的資料裝入進去。

6、客戶端在對JSON檔案呼叫成功之後,也就獲得了自己所需的資料,剩下的就是按照自己需求進行處理和展現了,這種獲取遠端資料的方式看起來非常像AJAX,但其實並不一樣。

7、為了便於客戶端使用資料,逐漸形成了一種非正式傳輸協議,人們把它稱作JSONP,該協議的一個要點就是允許使用者傳遞一個callback引數給服務端,然後服務端返回資料時會將這個callback引數作為函式名來包裹住JSON資料,這樣客戶端就可以隨意定製自己的函式來自動處理返回資料了。

JSONP的客戶端具體實現:
1、我們知道,哪怕跨域js檔案中的程式碼(當然指符合web指令碼安全策略的),web頁面也是可以無條件執行的。
遠端伺服器remoteserver.com根目錄下有個remote.js檔案程式碼如下:

alert('我是遠端檔案');
1

本地伺服器localserver.com下有個jsonp.html頁面程式碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>
12345678910

毫無疑問,頁面將會彈出一個提示窗體,顯示跨域呼叫成功。

2、現在我們在jsonp.html頁面定義一個函式,然後在遠端remote.js中傳入資料進行呼叫。

jsonp.html頁面程式碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函式,可以被跨域的remote.js檔案呼叫,遠端js帶來的資料是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>
123456789101112131415

remote.js檔案程式碼如下:

localHandler({"result":"我是遠端js帶來的資料"});
1

執行之後檢視結果,頁面成功彈出提示視窗,顯示本地函式被跨域的遠端js呼叫成功,並且還接收到了遠端js帶來的資料。
很欣喜,跨域遠端獲取資料的目的基本實現了,但是又一個問題出現了,我怎麼讓遠端js知道它應該呼叫的本地函式叫什麼名字呢?畢竟是jsonp的服務者都要面對很多服務物件,而這些服務物件各自的本地函式都不相同啊?我們接著往下看。

3、聰明的開發者很容易想到,只要服務端提供的js指令碼是動態生成的就行了唄,這樣呼叫者可以傳一個引數過去告訴服務端 “我想要一段呼叫XXX函式的js程式碼,請你返回給我”,於是伺服器就可以按照客戶端的需求來生成js指令碼並響應了。

看jsonp.html頁面的程式碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班資訊查詢結果後的回撥函式
    var flightHandler = function(data){
        alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '餘票 ' + data.tickets + ' 張。');
    };
    // 提供jsonp服務的url地址(不管是什麼型別的地址,最終生成的返回值都是一段javascript程式碼)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 建立script標籤,設定其屬性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script標籤加入head,此時呼叫開始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>
</body>
</html>
123456789101112131415161718192021

這次的程式碼變化比較大,不再直接把遠端js檔案寫死,而是編碼實現動態查詢,而這也正是jsonp客戶端實現的核心部分,本例中的重點也就在於如何完成jsonp呼叫的全過程。
我們看到呼叫的url中傳遞了一個code引數,告訴伺服器我要查的是CA1998次航班的資訊,而callback引數則告訴伺服器,我的本地回撥函式叫做flightHandler,所以請把查詢結果傳入這個函式中進行呼叫。
OK,伺服器很聰明,這個叫做flightResult.aspx的頁面生成了一段這樣的程式碼提供給jsonp.html

(服務端的實現這裡就不演示了,與你選用的語言無關,說到底就是拼接字串):
HTML 程式碼

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});
12345

我們看到,傳遞給flightHandler函式的是一個json,它描述了航班的基本資訊。執行一下頁面,成功彈出提示視窗,jsonp的執行全過程順利完成!

4、到這裡為止的話,相信你已經能夠理解jsonp的客戶端實現原理了吧?剩下的就是如何把程式碼封裝一下,以便於與使用者介面互動,從而實現多次和重複呼叫。

jQuery如何實現jsonp呼叫?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(一般預設為:callback)
             jsonpCallback:"flightHandler",//自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,也可以寫"?",jQuery會自動為你處理資料
             success: function(json){
                 alert('您查詢到航班資訊:票價: ' + json.price + ' 元,餘票: ' + json.tickets + ' 張。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
</html>
123456789101112131415161718192021222324252627

這裡針對ajax與jsonp的異同再做一些補充說明:

1、ajax和jsonp這兩種技術在呼叫方式上"看起來"很像,目的也一樣,都是請求一個url,然後把伺服器返回的資料進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝。

2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態新增script標籤來呼叫伺服器提供的js指令碼。

3、所以說,其實ajax與jsonp的區別不在於是否跨域,ajax通過服務端代理一樣可以實現跨域,jsonp本身也不排斥同域的資料的獲取。

4、還有就是,jsonp是一種方式或者說非強制性協議,如同ajax一樣,它也不一定非要用json格式來傳遞資料,如果你願意,字串都行,只不過這樣不利於用jsonp提供公開服務。

總而言之,jsonp不是ajax的一個特例,哪怕jquery等巨頭把jsonp封裝進了ajax,也不能改變這一點!

2、手寫單連結串列查詢倒數第k個節點

1、為了找出倒數第k個元素,最容易想到的辦法是首先遍歷一遍單連結串列,求出整個單連結串列的長度n,然後將倒數第k個,轉換為正數第n-k個,接下來遍歷一次就可以得到結果。但是該方法存在一個問題,即需要對連結串列進行兩次遍歷,第一次遍歷用於求解單連結串列的長度,第二次遍歷用於查詢正數第n-k個元素。
這種思路的時間複雜度是O(n),但需要遍歷連結串列兩次。

2、如果我們在遍歷時維持兩個指標,第一個指標從連結串列的頭指標開始遍歷,在第k-1步之前,第二個指標保持不動;在第k-1步開始,第二個指標也開始從連結串列的頭指標開始遍歷。由於兩個指標的距離保持在k-1,當第一個(走在前面的)指標到達連結串列的尾結點時,第二個指標(走在後面的)指標正好是倒數第k個結點。這種思路只需要遍歷連結串列一次。對於很長的連結串列,只需要把每個結點從硬碟匯入到記憶體一次。因此這一方法的時間效率前面的方法要高。

class Node{
	Node next=null;
	int data;
	public Node(int data){
		this.data=data;
	}
}
public class MyLinkedList {

	Node head=null;//連結串列頭的引用
	public Node findElem(Node head,int k){
		if(k<1||k>this.length()){
			return null;
		}
		Node p1=head;
		Node p2=head;
		for(int i=0;i<k;i++)
			p1=p1.next;
		while(p1!=null){
			p1=p1.next;
			p2=p2.next;
		}
		return p2;
	}
	public static void main(String[] args) {
		
		MyLinkedList list=new MyLinkedList();
		list.addNode(1);
		list.addNode(2);
		list.addNode(3);
		list.addNode(4);
		list.addNode(5);
		MyLinkedList p=new MyLinkedList();
		p.head=list.findElem(list.head, 3);
		p.printList();
		
	}

}
123456789101112131415161718192021222324252627282930313233343536373839

3、http請求頭,請求體,cookie在哪個裡面?url在哪裡面?

參考菜鳥教程HTTP專欄:http://www.runoob.com/http/http-tutorial.html
人人三面的時候問我http請求頭都有哪些值,答不上來。。GG
客戶端請求訊息
這裡寫圖片描述
伺服器響應訊息
HTTP響應也由四個部分組成,分別是:狀態行、訊息報頭、空行和響應正文。
這裡寫圖片描述

例項
下面例項是一點典型的使用GET來傳遞資料的例項:
客戶端請求:

GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
1234

服務端響應:

HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
123456789

輸出結果:

Hello World! My payload includes a trailing CRLF.
1

4、原型鏈的解釋

餓了麼面試的時候問到了,用友也問到了。沒答好,GG.
這裡寫圖片描述

5、對閉包的理解,實現一個暴露內部變數,而且外部可以訪問修改的函式

閉包的作用:
匿名自執行函式、快取、實現封裝(主要作用)、實現物件導向中的物件

var person = function(){    
    //變數作用域為函式內部,外部無法訪問    
    var name = "default";       
    return {    
       getName : function(){    
           return name;    
       },    
       setName : function(newName){    
           name = newName;    
       }    
    }    
}();    
print(person.name);//直接訪問,結果為undefined    
print(person.getName());    
person.setName("a");    
print(person.getName());    
//得到結果如下:  
undefined  
default  
a
1234567891011121314151617181920

6、基本的資料型別

5個簡單資料型別(基本資料型別)+ 1個複雜資料型別
undefiend, number string null boolean + object
ES6 新增Symbol

7、基本的兩列自適應佈局

左定右適應:

#div1{
	width: 100px;
	display: inline-block;
	background-color: black;
}
#div2{
	display: inline-block;
	position: absolute;
	left: 100px;
	right: 0px;
	background-color: red;
}
123456789101112

8、unix中常用的命令列

雖然上過linux課,但是命令忘得差不多了 尷尬。。。

9、OSI模型,HTTP,TCP,UDP分別在哪些層

這個可以參考我另一個部落格:
http://blog.csdn.net/qq_22944825/article/details/78160659
OSI:物理層-資料鏈路層-網路層-傳輸層-會話層-表現層-應用層
這裡寫圖片描述

10、解釋平衡二叉樹,以及在資料結構中的應用(紅黑樹)

11、快排的時間複雜度和空間複雜度

一個特別好的總結的部落格:

12、手寫一個jQuery外掛

1、$.extend(src)
  該方法就是將src合併到jquery的全域性物件中去,如:

 $.extend({
	  hello:function(){alert('hello');}
	  });
123

2、$.fn.extend(src)
  該方法將src合併到jquery的例項物件中去,如:

 $.fn.extend({
  hello:function(){alert('hello');}
 });
123

13、在jquery方法和原型上面新增方法的區別和實現,以及jquery物件的實現

參考上一個問題答案~

使用jquery的第一件事就是要使用jquery物件,jquery物件和javascript中的DOM物件是不同的。

什麼是jquery物件?jquery將一個DOM物件轉化為jquery物件後就可以使用jquery類庫提供的各種函式。可以將jquery物件理解為一個類,並且封裝了很多的方法,而且可以動態的通過載入外掛擴充套件這個類,類似於C#中的分佈類partial class。

除了jQuery工具函式,jQuery的操作都是從jQuery物件開始。比如:

	attr(key,value)
	
	<img id="myphoto" alt="my photo" src=""/>
	
	$("#myphoto").attr("src","/pic/1.jpg");
12345

jQuery物件是一個特殊的集合物件。即使只有一個元素,jQuery物件仍然是一個集合。說其特殊是因為實際上jQuery物件是包含一個集合物件和各種函式的類。

14、手寫一個遞迴函式

 function fact(num) {
	if (num <= 1) {
		return 1;             
	} else {
		return num * fact(num - 1);            
	}
} 
1234567

以下程式碼可導致出錯:

var anotherFact = fact; 
 fact = null; 
 alert(antherFact(4)); //出錯 
123

由於fact已經不是函式了,所以出錯。
用arguments.callee可解決問題,這是一個指向正在執行的函式的指標,arguments.callee返回正在被執行的對現象。
新的函式為:

function fact(num) {
            if (num <= 1) {
                return 1;
            } else {
                return num * arguments.callee(num - 1); //此處更改了。 
            }
}
var anotherFact = fact;
fact = null;
alert(antherFact(4)); //結果為24.
12345678910

15、對前端路由的理解?前後端路由的區別?

前端的路由和後端的路由在實現技術上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現之前,前端的路由都是通過 hash 來實現的,hash 能相容低版本的瀏覽器。

http://10.0.0.1/
http://10.0.0.1/#/about
http://10.0.0.1/#/concat
123

服務端路由:每跳轉到不同的URL,都是重新訪問服務端,然後服務端返回頁面,頁面也可以是服務端獲取資料,然後和模板組合,返回HTML,也可以是直接返回模板HTML,然後由前端JS再去請求資料,使用前端模板和資料進行組合,生成想要的HTML。

前端路由:每跳轉到不同的URL都是使用前端的錨點路由,實際上只是JS根據URL來操作DOM元素,根據每個頁面需要的去服務端請求資料,返回資料後和模板進行組合,當然模板有可能是請求服務端返回的,這就是 SPA 單頁程式。

在js可以通過window.location.hash讀取到路徑加以解析之後就可以響應不同路徑的邏輯處理。

history 是 HTML5 才有的新 API,可以用來操作瀏覽器的 session history (會話歷史)。基於 history 來實現的路由可以和最初的例子中提到的路徑規則一樣。

H5還新增了一個hashchange事件,也是很有用途的一個新事件:

當頁面hash(#)變化時,即會觸發hashchange。錨點Hash起到引導瀏覽器將這次記錄推入歷史記錄棧頂的作用,window.location物件處理“#”的改變並不會重新載入頁面,而是將之當成新頁面,放入歷史棧裡。並且,當前進或者後退或者觸發hashchange事件時,我們可以在對應的事件處理函式中註冊ajax等操作!
但是hashchange這個事件不是每個瀏覽器都有,低階瀏覽器需要用輪詢檢測URL是否在變化,來檢測錨點的變化。當錨點內容(location.hash)被操作時,如果錨點內容發生改變瀏覽器才會將其放入歷史棧中,如果錨點內容沒發生變化,歷史棧並不會增加,並且也不會觸發hashchange事件。

16、介紹一下webpack和gulp,以及專案中具體的使用

17、你對es6的瞭解

參見阮大大的部落格
http://es6.ruanyifeng.com/

18、解釋一下vue和react,以及異同點

異同點:vue官網給過答案
https://cn.vuejs.org/v2/guide/comparison.html

只簡單的用過vue,用vue寫了一個日程表,請賜教哦~

https://yyywwwqqq.coding.me/schedule/dist/

原始碼地址:
https://coding.net/u/yyywwwqqq/p/schedule/git

19、關於平衡二叉樹

平衡二叉搜尋樹(Self-balancing binary search tree)又被稱為AVL樹(有別於AVL演算法),且具有以下性質:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹,同時,平衡二叉樹必定是二叉搜尋樹,反之則不一定。平衡二叉樹的常用實現方法有紅黑樹、AVL、替罪羊樹、Treap、伸展樹等。 最小二叉平衡樹的節點的公式如下 F(n)=F(n-1)+F(n-2)+1 這個類似於一個遞迴的數列,可以參考Fibonacci(斐波那契)數列,1是根節點,F(n-1)是左子樹的節點數量,F(n-2)是右子樹的節點數量。

20、前後端分離的意義以及對前端工程化的理解

21、使用css實現一個三角形

利用border去畫~
先看一下border的佈局,如圖:
這裡寫圖片描述
所以三角形:
1.設定寬度、高度為0
這裡寫圖片描述
2.不設定border-top
這裡寫圖片描述
3.設定左右border顏色為transparent–透明
這裡寫圖片描述

22、用promise手寫ajax

function getJson(url){
    return new Promise((resolve, reject) =>{
        var xhr = new XMLHttpRequest();
        xhr.open('open', url, true);
        xhr.onreadystatechange = function(){
            if(this.readyState == 4){
                if(this.status = 200){
                    resolve(this.responseText, this)
                }else{
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)    
                }
            }
        }
        xhr.send()
    })
}

function postJSON(url, data) {
    return new Promise( (resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open("POST", url, true)
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this)
                } else {
                    var resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }

        xhr.send(JSON.stringify(data))
    })
}

getJSON('/api/v1/xxx')    // => 這裡面是就try
.catch( error => {
  // dosomething          // => 這裡就是catch到了error,如果處理error以及返還合適的值
})
.then( value => {
  // dosomething          // 這裡就是final
})
12345678910111213141516171819202122232425262728293031323334353637383940414243444546

23、手寫一個類的繼承,並解釋一下

繼承的形式有很多中,js高程裡面歸納了其中,我簡單說一下前三種。
1.原型繼承

function Parent(){
	this.name = "parent";
}
Parent.prototype.getName = function(){
	return this.name;
}

function Child(){
	this.name = "child";
}

//繼承parent
Child.prototype = new Parent();
12345678910111213

2.建構函式繼承

function Animal(name){
	this.name = name;
	this.eat = function(){
		consoel.log(this.name + "吃飯");
    }
}
var cat = new Animal("maomi");
cat.name;
cat.eat();
123456789

缺點是:
3.組合繼承

24、解釋一下call函式和apply函式的作用,以及用法

改變this的指向。
this的指向問題,在你不知道的js這本書中(神書)做了四點歸納:
1.預設繫結 (指 直接呼叫 foo(), this指向window)
2.隱式繫結(obj.foo(), this指向obj 這裡會出現很多坑,下面的問題應該會有解答)
3.顯示繫結(利用call、apply、bind改變this)
4.new(var cat = new Animal() , this指向cat物件)

25、你說自己抗壓能力強,具體表現在哪裡?

26、對前端前景的展望,以後前端會怎麼發展

27、手寫第一次面試沒有寫出來的連結串列問題,要求用es6寫

28、平時是怎麼學技術的?

29、平時大學裡面時間是怎麼規劃的?

30、接下來有什麼計劃?這個學期和下個學期的計劃是?

31、專案中遇到的難點,或者你學習路上的難點

32、你是通過什麼方法和途徑來學習前端的

33、手寫一個簡單遍歷演算法

34、解釋一下react和vue,以及區別

35、你在團隊中更傾向於什麼角色?

36、對java的理解

37、介紹node.js,並且介紹你用它做的專案

38、手寫一個js的深克隆

function deepCopy(obj){
	//判斷是否是簡單資料型別,
	if(typeof obj == "object"){
		//複雜資料型別
		var result = obj.constructor == Array ? [] : {};
		for(let i in obj){
			result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
		}
	}else {
		//簡單資料型別 直接 == 賦值
		var result = obj;
	}
	return result;
}
1234567891011121314

39、for函式裡面setTimeout非同步問題

40、手寫歸併排序

<1>.長度為n(n>1),把該輸入序列分成兩個長度為n/2的子序列;
<2>.對這兩個子序列分別採用歸併排序,直到長度n小於2;
<3>.將兩個排序好的子序列合併成一個最終的排序序列。

function mergeSort(arr) { 
	var len = arr.length;
	if(len < 2) {
		return arr;
	} else {
		middle = Math.floor(len / 2);
		var left = arr.slice(0, middle);
		var right = arr.splice(middle);
		return merge(mergeSort(left), mergeSort(right));
	}

}

function merge(left, right) {
	var result = [];
	while(left.length && right.length) {
		left[0] > right[0] ? result.push(right.shift()): result.push(left.shift());
	}
	if(left.length) {
		result = result.concat(left);
	}
	if(right.length) {
		result = result.concat(right);
	}
	return result;
}
1234567891011121314151617181920212223242526

41、介紹自己的專案

42、實現兩個排序陣列的合併

參考42題中的merge函式。

43、手寫一個原生ajax

ajax:一種請求資料的方式,不需要重新整理整個頁面;
ajax的技術核心是 XMLHttpRequest 物件;
ajax 請求過程:建立 XMLHttpRequest 物件、連線伺服器、傳送請求、接收響應資料;

一個在stackoverflow的高分回答結合上面的程式碼,給出get和post的兩種不同請求方法:

var ajax = {};
ajax.x = function () {
	if (typeof XMLHttpRequest !== 'undefined') {
		return new XMLHttpRequest();
	}
	var versions = [
	"MSXML2.XmlHttp.6.0",
	"MSXML2.XmlHttp.5.0",
	"MSXML2.XmlHttp.4.0",
	"MSXML2.XmlHttp.3.0",
	"MSXML2.XmlHttp.2.0",
	"Microsoft.XmlHttp"
	];

	var xhr;
	for (var i = 0; i < versions.length; i++) {
		try {
			xhr = new ActiveXObject(versions[i]);
			break;
		} catch (e) {
		}
	}
	return xhr;
};

ajax.send = function (url, method, data, success,fail,async) {
	if (async === undefined) {
		async = true;
	}
	var x = ajax.x();
	x.open(method, url, async);
	x.onreadystatechange = function () {
		if (x.readyState == 4) {
			var status = x.status;
			if (status >= 200 && status < 300) {
				success && success(x.responseText,x.responseXML)
			} else {
				fail && fail(status);
			}
			
		}
	};
	if (method == 'POST') {
		x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	}
	x.send(data)
};

ajax.get = function (url, data, callback, fail, async) {
	var query = [];
	for (var key in data) {
		query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
	}
	ajax.send(url + (query.length ? '?' + query.join('&') : ''), 'GET', null, success, fail, async)
};

ajax.post = function (url, data, callback, fail, async) {
	var query = [];
	for (var key in data) {
		query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
	}
	ajax.send(url,'POST', query.join('&'), success, fail, async)
};
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263

使用方法:GET

ajax.get('/test.php', {foo: 'bar'}, function(response,xml) {
	//success
},
function(status){
	//fail
});
123456

POST

ajax.post('/test.php', {foo: 'bar'}, function(response,xml) {
	//succcess

},function(status){
	//fail
	
});
1234567

44、手寫一個promise版的ajax

45、手寫實現一個promise

46、手寫實現requireJS模組實現

47、手寫實現jquery裡面的insertAfter

48、react和vue的介紹以及異同

49、AMD和CMD,commonJS的區別

50、介紹一下backbone

51、瞭解過SEO嗎?

52、低版本瀏覽器不支援HTML5標籤怎麼解決?

53、用js使低版本瀏覽器支援HTML5標籤 底層是怎麼實現的?

54、實現一個佈局:左邊固定寬度為200,右邊自適應,而且滾動條要自動選擇只出現最高的那個

55、畫出盒子模型,要使谷歌瀏覽器的盒子模型顯示得跟IE瀏覽器一致(讓谷歌跟ie一致,不是ie跟谷歌一致),該怎麼做?

56、手寫JS實現類繼承,講原型鏈原理,並解釋new一個物件的過程都發生了什麼

57、Array物件自帶的方法,一一列舉

58、若干個數字,怎麼選出最大的五個

59、Array物件自帶的排序函式底層是怎麼實現的?

60、常用的排序演算法有哪些,介紹一下選擇排序

61、瞭解navigator物件嗎?

62、手寫一個正規表示式,驗證郵箱

63、link和@import引入CSS的區別?

64、剛才說有些瀏覽器不相容@import,具體指哪些瀏覽器?

65、介紹一下cookie,localstorage,sessionstorage,session

66、jquery繫結click的方法有幾種

67、你的優點/競爭力

68、移動端適配問題

69、react的難點在哪裡

70、做過css動畫嗎

71、如何優化網站

72、以後的規劃

73、你做過最困難的事情是啥?

74、css3 html5新特性

75、閉包,ES6,跨域

76、問做過啥專案,用到什麼技術,遇到什麼困難

77、相容性

78、盒子模型

79、Array的unshift() method的作用是什麼?如何連線兩個Array?如何在Array裡移除一個元素?

80、用紙筆寫一個Closure,任意形式和內容

81、知不知道Array-like Object?

82、如何用Native JavaScript來讀寫Cookie?

83、知不知道CSS Box-model?

84、如何做一個AJAX Request?

85、Cross-domain access有沒有了解?

86、前端安全方面有沒有了解?XSS和CSRF如何攻防?

87、HTTP Response的Header裡面都有些啥?

88、知不知道HTTP2?

89、輸入URL後發生了什麼?

90、new operator實際上做了什麼?

91、物件導向的屬性有哪些?

92、做一個兩欄佈局,左邊fixed width,右邊responsive,用紙筆手寫

93、講一下AJAX Request

94、講一下Cross-domain access

95、介紹一下做過的專案

96、問到了多個伺服器怎麼弄,架構之類的

97、angular的渲染流程

98、髒檢查

99、nodejs的架構、優缺點、回撥

100、css 盒模型

101、css 佈局,左邊定寬右邊自適應

102、冒泡和捕獲,事件流哪三個階段?

103、實現事件代理

104、原型鏈

105、繼承的兩種方法

106、ajax,原生ajax的四個過程

107、閉包,簡單說一個閉包的應用,然後閉包的主要作用是什麼

108、css:兩個塊狀元素上下的margin-top和margin-bottom會重疊。啥原因?怎麼解決?

109、js:寫一個遞迴。就是每隔5秒呼叫一個自身,一共100次

110、cookie和session有什麼區別

111、網路分層結構

112、你的不足是什麼?

113、做了那麼多專案,有沒有自己的歸納總結

114、工程怎麼進行檔案管理

115、less和sass掌握程度

116、Cookie 是否會被覆蓋,localStorage是否會被覆蓋

117、事件代理js實現

118、Css實現動畫效果

119、Animation還有哪些其他屬性

120、Css實現三列布局

121、Css實現保持長寬比1:1

122、Css實現兩個自適應等寬元素中間空10個畫素

123、requireJS的原理是什麼

124、如何保持登入狀態

125、浮動的原理以及如何清除浮動

126、Html的語義化

127、原生js新增class怎麼新增,如果本身已經有class了,會不會覆蓋,怎麼保留?

128、Jsonp的原理。怎麼去讀取一個script裡面的資料?

129、如果頁面初始載入的時候把ajax請求返回的資料存在localStorage裡面,然後每次呼叫的時候去localStorage裡面取數,是否可行。

130、304是什麼意思?有沒有方法不請求不經過伺服器直接使用快取

131、http請求頭有哪些欄位

132、陣列去除一個函式。用arr.splice。又問splice返回了什麼?應該返回的是去除的元素。

133、js非同步的方法(promise,generator,async)

134、Cookie跨域請求能不能帶上

135、最近看什麼開源專案?

136、commonJS和AMD

137、平時是怎麼學習的?

138、為什麼要用translate3d?

139、物件中key-value的value怎麼再放一個物件?

140、Get和post的區別?

145、Post一個file的時候file放在哪的?

146、說說你對元件的理解

147、元件的html怎麼進行管理

148、js的非同步載入,promise的三種狀態,ES7中的async用過麼

149、靜態屬性怎麼繼承

150、js原型鏈的繼承

151、jquery和zepto有什麼區別

152、angular的雙向繫結原理

153、angular和react的認識

154、MVVM是什麼

155、移動端是指手機瀏覽器,還是native,還是hybrid

156、你用了移動端的什麼庫類和框架?

157、移動端要注意哪些?

158、適配有去考慮麼,retina螢幕啊?

159、rem是什麼?em是什麼?如果上一層就是根root了,em和rem等價麼?

160、怎麼測試的?會自動化測試麼?

161、你覺得你什麼技術最擅長?

162、你平時有沒有什麼技術的沉澱?

163、單向連結串列怎麼查詢有沒有環?

164、怎麼得到一個頁面的a標籤?

165、怎麼在頁面裡放置一個很簡單的圖示,不能用img和background-img?

166、正規表示式判斷url

167、怎麼去除字串前後的空格

168、實現頁面的區域性重新整理

169、絕對定位與相對定位的區別

170、js輪播實現思路

171、使用js畫一個拋物線,拋物線上有個小球隨著拋物線運動,有兩個按鈕能使小球繼續運動停止運動

172、java五子棋,說下實現思路

173、如何讓各種情況下的div居中(絕對定位的div,垂直居中,水平居中)?

174、display有哪些值?說明他們的作用

175、css定義的權重

176、requirejs實現原理

177、requirejs怎麼防止重複載入

178、ES6裡頭的箭頭函式的this物件與其他的有啥區別

179、tcp/udp區別

180、tcp三次握手過程

181、xss與csrf的原理與怎麼防範

182、mysql與 MongoDB的區別

183、w3c事件與IE事件的區別

184、有沒有上傳過些什麼npm模組

185、IE與W3C怎麼阻止事件的冒泡

186、gulp底層實現原理

187、webpack底層實現原理

188、gulp與webpack區別

189、vuejs與angularjs的區別

190、vuex是用來做什麼的

191、說下你知道的響應狀態碼

192、ajax的過程以及 readyState幾個狀態的含義

193、你除了前端之外還會些什麼?

194、cookie與session的區別

195、一些關於php與java的問題

196、你覺得你哪個專案是你做的最好的

197、說說你在專案中遇到了哪些困難,是怎麼解決的

198、前端優化你知道哪些

199、webpack是用來幹嘛的

200、webpack與gulp的區別

201、es6與es7瞭解多少

202、說下你知道的響應狀態碼

203、看過哪些框架的原始碼

204、遇到過哪些瀏覽器相容性問題

205、清除浮動有哪幾種方式,分別說說

206、你知道有哪些跨域方式,分別說說

207、JavaScript有哪幾種型別的值

208、使用 new操作符時具體是幹了些什麼

209、學習前端的方法以及途徑

210、怎麼實現兩個大整數的相乘,說下思路

211、你學過資料結構沒,說說你都瞭解些什麼

212、你學過計算機作業系統沒,說說你都瞭解些什麼

213、你學過計算機組成原理沒,說說你都瞭解些什麼

214、你學過演算法沒,說說你都瞭解些什麼

215、說下選擇排序,氣泡排序的實現思路

216、用過哪些框架

217、讓你設計一個前端css框架你怎麼做

218、瞭解哪些設計模式說說看

219、說下你所瞭解的設計模式的優點

220、vue原始碼結構

221、狀態碼

222、瀏覽器快取的區別

223、304與200讀取快取的區別

224、http請求頭有哪些,說說看你瞭解哪些

225、js中this的作用

226、js中上下文是什麼

227、js有哪些函式能改變上下文

228、你所瞭解的跨域的方法都說說看你瞭解的?

229、要是讓你自己寫一個js框架你會用到哪些設計模式

230、平常在專案中用到過哪些設計模式,說說看

231、一來給了張紙要求寫js自定義事件

232、前端跨域的方法

233、call與apply的區別

234、h5有個api能定位你知道是哪個嗎?

235、vue與angularjs中雙向資料繫結是怎樣實現的?

236、webpack怎樣配置?

237、nodejs中的檔案怎麼讀寫?

238、link和@import有什麼區別?

239、cookies,sessionStorage 和 localStorage 的區別

240、看過哪些前端的書?平時是怎麼學習的

241、說下你所理解的mvc與mvvc

242、position有哪些值,說下各自的作用

243、寫個從幾個li中取下標的閉包程式碼

244、你的職業規劃是怎麼樣的?

245、移動端效能優化

246、lazyload如何實現

247、點透問題

248、前端安全

249、原生js模板引擎

250、repaint和reflow區別

251、requirejs如何避免迴圈依賴?

252、實現佈局:左邊一張圖片,右邊一段文字(不是環繞)

253、window.onload和$(document).ready()的區別,瀏覽器載入轉圈結束時哪個時間點?

254、form表單當前頁面無重新整理提交 target iframe

255、setTimeout和setInterval區別,如何互相實現?

256、如何避免多重回撥—promise,promise簡單描述一下,如何在外部進行resolve()

257、margin坍塌?水平方向會不會坍塌?

258、偽類和偽元素區別

259、vue如何實現父子元件通訊,以及非父子元件通訊

260、陣列去重

261、使用flex佈局實現三等分,左右兩個元素分別貼到左邊和右邊,垂直居中

262、平時如何學前端的,看了哪些書,關注了哪些公眾號

263、實現bind函式

264、陣列和連結串列區別,分別適合什麼資料結構

265、對mvc的理解

266、描述一個印象最深的專案,在其中擔任的角色,解決什麼問題

267、http狀態碼。。。401和403區別?

268、描述下二分查詢

269、為什麼選擇前端,如何學習的,看了哪些書,《js高階程式設計》和《你不知道的js》有什麼區別,看書,看部落格,看公眾號三者的時間是如何分配的?

270、如何評價BAT?

271、描述下在實習中做過的一個專案,解決了什麼問題,在其中擔任了什麼角色?這個過程存在什麼問題,有什麼值得改進的地方?

272、如何看待加班,如果有個專案需要連續一個月加班,你怎麼看?

273、遇到的壓力最大的一件事是什麼?如何解決的?

274、平時有什麼愛好

275、自身有待改進的地方

276、n長的陣列放入n+1個數,不能重複,找出那個缺失的數

277、手裡有什麼offer

278、你對於第一份工作最看重的三個方面是什麼?

279、如何評價現在的前端?

280、用原生js實現核取方塊選擇以及全選非全選功能

281、用4個顏色給一個六面體上色有多少種情況

282、amd和cmd區別

283、為什麼選擇前端,移動端效能優化

284、vue的特點?雙向資料繫結是如何實現的

285、Object.defineProperty

286、演算法題:陣列去重,去除重複兩次以上的元素,程式碼題:巢狀的ul-li結構,根據input中輸入的內容,去除相應的li節點,且如果某個巢狀的ul下面的li都被移除,則該ul的父li節點也要被移除

287、頁面載入過程

288、瀏覽器如何實現圖片快取

Vue常見面試題-1

一、對於MVVM的理解?

MVVM 是 Model-View-ViewModel 的縮寫。
Model代表資料模型,也可以在Model中定義資料修改和操作的業務邏輯。
View 代表UI 元件,它負責將資料模型轉化成UI 展現出來。
ViewModel 監聽模型資料的改變和控制檢視行為、處理使用者互動,簡單理解就是一個同步View 和 Model的物件,連線Model和View。
在MVVM架構下,View 和 Model 之間並沒有直接的聯絡,而是通過ViewModel進行互動,Model 和 ViewModel 之間的互動是雙向的, 因此View 資料的變化會同步到Model中,而Model 資料的變化也會立即反應到View 上。
ViewModel 通過雙向資料繫結把 View 層和 Model 層連線了起來,而View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發者只需關注業務邏輯,不需要手動操作DOM, 不需要關注資料狀態的同步問題,複雜的資料狀態維護完全由 MVVM 來統一管理。
bg2015020110.png

二、Vue的生命週期

beforeCreate(建立前) 在資料觀測和初始化事件還未開始
created(建立後) 完成資料觀測,屬性和方法的運算,初始化事件, e l 屬 性 還 沒 有 顯 示 出 來 ∗ ∗ b e f o r e M o u n t ∗ ∗ ( 載 入 前 ) 在 掛 載 開 始 之 前 被 調 用 , 相 關 的 r e n d e r 函 數 首 次 被 調 用 。 實 例 已 完 成 以 下 的 配 置 : 編 譯 模 板 , 把 d a t a 裡 面 的 數 據 和 模 板 生 成 h t m l 。 注 意 此 時 還 沒 有 掛 載 h t m l 到 頁 面 上 。 ∗ ∗ m o u n t e d ∗ ∗ ( 載 入 後 ) 在 e l 被 新 創 建 的 v m . el屬性還沒有顯示出來 **beforeMount**(載入前) 在掛載開始之前被呼叫,相關的render函式首次被呼叫。例項已完成以下的配置:編譯模板,把data裡面的資料和模板生成html。注意此時還沒有掛載html到頁面上。 **mounted**(載入後) 在el 被新建立的 vm. elbeforeMount調render調datahtmlhtmlmountedelvm.el 替換,並掛載到例項上去之後呼叫。例項已完成以下的配置:用上面編譯好的html內容替換el屬性指向的DOM物件。完成模板中的html渲染到html頁面中。此過程中進行ajax互動。
beforeUpdate(更新前) 在資料更新之前呼叫,發生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步地更改狀態,不會觸發附加的重渲染過程。
updated(更新後) 在由於資料更改導致的虛擬DOM重新渲染和打補丁之後呼叫。呼叫時,元件DOM已經更新,所以可以執行依賴於DOM的操作。然而在大多數情況下,應該避免在此期間更改狀態,因為這可能會導致更新無限迴圈。該鉤子在伺服器端渲染期間不被呼叫。
beforeDestroy(銷燬前) 在例項銷燬之前呼叫。例項仍然完全可用。
destroyed(銷燬後) 在例項銷燬之後呼叫。呼叫後,所有的事件監聽器會被移除,所有的子例項也會被銷燬。該鉤子在伺服器端渲染期間不被呼叫。
1.什麼是vue生命週期?
答: Vue 例項從建立到銷燬的過程,就是生命週期。從開始建立、初始化資料、編譯模板、掛載Dom→渲染、更新→渲染、銷燬等一系列過程,稱之為 Vue 的生命週期。

2.vue生命週期的作用是什麼?
答:它的生命週期中有多個事件鉤子,讓我們在控制整個Vue例項的過程時更容易形成好的邏輯。

3.vue生命週期總共有幾個階段?
答:它可以總共分為8個階段:建立前/後, 載入前/後,更新前/後,銷燬前/銷燬後。

4.第一次頁面載入會觸發哪幾個鉤子?
答:會觸發 下面這幾個beforeCreate, created, beforeMount, mounted 。

5.DOM 渲染在 哪個週期中就已經完成?
答:DOM 渲染在 mounted 中就已經完成了。

三、 Vue實現資料雙向繫結的原理:Object.defineProperty()

vue實現資料雙向繫結主要是:採用資料劫持結合釋出者-訂閱者模式的方式,通過**Object.defineProperty()**來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應監聽回撥。當把一個普通 Javascript 物件傳給 Vue 例項來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty 將它們轉為 getter/setter。使用者看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。

vue的資料雙向繫結 將MVVM作為資料繫結的入口,整合Observer,Compile和Watcher三者,通過Observer來監聽自己的model的資料變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}}),最終利用watcher搭起observer和Compile之間的通訊橋樑,達到資料變化 —>檢視更新;檢視互動變化(input)—>資料model變更雙向繫結效果。

js實現簡單的雙向繫結

<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
</div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>

四、Vue元件間的引數傳遞

1.父元件與子元件傳值
父元件傳給子元件:子元件通過props方法接受資料;
子元件傳給父元件:$emit方法傳遞引數
2.非父子元件間的資料傳遞,兄弟元件傳值
eventBus,就是建立一個事件中心,相當於中轉站,可以用它來傳遞事件和接收事件。專案比較小時,用這個比較合適。(雖然也有不少人推薦直接用VUEX,具體來說看需求咯。技術只是手段,目的達到才是王道。)

五、Vue的路由實現:hash模式 和 history模式

**hash模式:**在瀏覽器中符號“#”,#以及#後面的字元稱之為hash,用window.location.hash讀取;
特點:hash雖然在URL中,但不被包括在HTTP請求中;用來指導瀏覽器動作,對服務端安全無用,hash不會重載入頁面。
hash 模式下,僅 hash 符號之前的內容會被包含在請求中,如 http://www.xxx.com,因此對於後端來說,即使沒有做到對路由的全覆蓋,也不會返回 404 錯誤。

**history模式:**history採用HTML5的新特性;且提供了兩個新方法:pushState(),replaceState()可以對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變更。
history 模式下,前端的 URL 必須和實際向後端發起請求的 URL 一致,如 http://www.xxx.com/items/id。後端如果缺少對 /items/id 的路由處理,將返回 404 錯誤。Vue-Router 官網裡如此描述:“不過這種模式要玩好,還需要後臺配置支援……所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。”

六、Vue與Angular以及React的區別?

(版本在不斷更新,以下的區別有可能不是很正確。我工作中只用到vue,對angular和react不怎麼熟)
1.與AngularJS的區別
相同點:
都支援指令:內建指令和自定義指令;都支援過濾器:內建過濾器和自定義過濾器;都支援雙向資料繫結;都不支援低端瀏覽器。

不同點:
AngularJS的學習成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直觀;在效能上,AngularJS依賴對資料做髒檢查,所以Watcher越多越慢;Vue.js使用基於依賴追蹤的觀察並且使用非同步佇列更新,所有的資料都是獨立觸發的。

2.與React的區別
相同點:
React採用特殊的JSX語法,Vue.js在元件開發中也推崇編寫.vue特殊檔案格式,對檔案內容都有一些約定,兩者都需要編譯後使用;中心思想相同:一切都是元件,元件例項之間可以巢狀;都提供合理的鉤子函式,可以讓開發者定製化地去處理需求;都不內建列數AJAX,Route等功能到核心包,而是以外掛的方式載入;在元件開發中都支援mixins的特性。
不同點:
React採用的Virtual DOM會對渲染出來的結果做髒檢查;Vue.js在模板中提供了指令,過濾器等,可以非常方便,快捷地操作Virtual DOM。

七、vue路由的鉤子函式

首頁可以控制導航跳轉,beforeEach,afterEach等,一般用於頁面title的修改。一些需要登入才能調整頁面的重定向功能。

beforeEach主要有3個引數to,from,next:

to:route即將進入的目標路由物件,

from:route當前導航正要離開的路由

next:function一定要呼叫該方法resolve這個鉤子。執行效果依賴next方法的呼叫引數。可以控制網頁的跳轉。

八、vuex是什麼?怎麼使用?哪種功能場景使用它?

只用來讀取的狀態集中放在store中; 改變狀態的方式是提交mutations,這是個同步的事物; 非同步邏輯應該封裝在action中。
在main.js引入store,注入。新建了一個目錄store,…… export 。
場景有:單頁應用中,元件之間的狀態、音樂播放、登入狀態、加入購物車
圖片描述

state
Vuex 使用單一狀態樹,即每個應用將僅僅包含一個store 例項,但單一狀態樹和模組化並不衝突。存放的資料狀態,不可以直接修改裡面的資料。
mutations
mutations定義的方法動態修改Vuex 的 store 中的狀態或資料。
getters
類似vue的計算屬性,主要用來過濾一些資料。
action
actions可以理解為通過將mutations裡面處裡資料的方法變成可非同步的處理資料的方法,簡單的說就是非同步運算元據。view 層通過 store.dispath 來分發 action。

const store = new Vuex.Store({ //store例項
      state: {
         count: 0
             },
      mutations: {                
         increment (state) {
          state.count++
         }
          },
      actions: { 
         increment (context) {
          context.commit('increment')
   }
 }
})

modules
專案特別複雜的時候,可以讓每一個模組擁有自己的state、mutation、action、getters,使得結構非常清晰,方便管理。

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
 }
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
 }

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
})

九、vue-cli如何新增自定義指令?

1.建立區域性指令

var app = new Vue({
    el: '#app',
    data: {    
    },
    // 建立指令(可以多個)
    directives: {
        // 指令名稱
        dir1: {
            inserted(el) {
                // 指令中第一個引數是當前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 對DOM進行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        }
    }
})

2.全域性指令

Vue.directive('dir2', {
    inserted(el) {
        console.log(el);
    }
})

3.指令的使用

<div id="app">
    <div v-dir1></div>
    <div v-dir2></div>
</div>

十、vue如何自定義一個過濾器?

html程式碼:

<div id="app">
     <input type="text" v-model="msg" />
     {{msg| capitalize }}
</div>

JS程式碼:

var vm=new Vue({
    el:"#app",
    data:{
        msg:''
    },
    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }
})

全域性定義過濾器

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

過濾器接收表示式的值 (msg) 作為第一個引數。capitalize 過濾器將會收到 msg的值作為第一個引數。

十一、對keep-alive 的瞭解?

keep-alive是 Vue 內建的一個元件,可以使被包含的元件保留狀態,或避免重新渲染。
在vue 2.1.0 版本之後,keep-alive新加入了兩個屬性: include(包含的元件快取) 與 exclude(排除的元件不快取,優先順序大於include) 。

使用方法

<keep-alive include='include_components' exclude='exclude_components'>
  <component>
    <!-- 該元件是否快取取決於include和exclude屬性 -->
  </component>
</keep-alive>

引數解釋
include - 字串或正規表示式,只有名稱匹配的元件會被快取
exclude - 字串或正規表示式,任何名稱匹配的元件都不會被快取
include 和 exclude 的屬性允許元件有條件地快取。二者都可以用“,”分隔字串、正規表示式、陣列。當使用正則或者是陣列時,要記得使用v-bind 。

使用示例

<!-- 逗號分隔字串,只有元件a與b被快取。 -->
<keep-alive include="a,b">
  <component></component>
</keep-alive>

<!-- 正規表示式 (需要使用 v-bind,符合匹配規則的都會被快取) -->
<keep-alive :include="/a|b/">
  <component></component>
</keep-alive>

<!-- Array (需要使用 v-bind,被包含的都會被快取) -->
<keep-alive :include="['a', 'b']">
  <component></component>
</keep-alive>

十二、一句話就能回答的面試題

1.css只在當前元件起作用
答:在style標籤中寫入scoped即可 例如:

2.v-if 和 v-show 區別
答:v-if按照條件是否渲染,v-show是display的block或none;

3.$route$router的區別
答:$route是“路由資訊物件”,包括path,params,hash,query,fullPath,matched,name等路由資訊引數。而$router是“路由例項”物件包括了路由的跳轉方法,鉤子函式等。

4.vue.js的兩個核心是什麼?
答:資料驅動、元件系統

5.vue幾種常用的指令
答:v-for 、 v-if 、v-bind、v-on、v-show、v-else

6.vue常用的修飾符?
答:.prevent: 提交事件不再過載頁面;.stop: 阻止單擊事件冒泡;.self: 當事件發生在該元素本身而不是子元素的時候會觸發;.capture: 事件偵聽,事件發生的時候會呼叫

7.v-on 可以繫結多個方法嗎?
答:可以

8.vue中 key 值的作用?
答:當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它預設用“就地複用”策略。如果資料項的順序被改變,Vue 將不會移動 DOM 元素來匹配資料項的順序, 而是簡單複用此處每個元素,並且確保它在特定索引下顯示已被渲染過的每個元素。key的作用主要是為了高效的更新虛擬DOM。

9.什麼是vue的計算屬性?
答:在模板中放入太多的邏輯會讓模板過重且難以維護,在需要對資料進行復雜處理,且可能多次使用的情況下,儘量採取計算屬性的方式。好處:①使得資料處理結構清晰;②依賴於資料,資料更新,處理結果自動更新;③計算屬性內部this指向vm例項;④在template呼叫時,直接寫計算屬性名即可;⑤常用的是getter方法,獲取資料,也可以使用set方法改變資料;⑥相較於methods,不管依賴的資料變不變,methods都會重新計算,但是依賴資料不變的時候computed從快取中獲取,不會重新計算。

10.vue等單頁面應用及其優缺點
答:優點:Vue 的目標是通過儘可能簡單的 API 實現響應的資料繫結和組合的檢視元件,核心是一個響應的資料繫結系統。MVVM、資料驅動、元件化、輕量、簡潔、高效、快速、模組友好。
缺點:不支援低版本的瀏覽器,最低只支援到IE9;不利於SEO的優化(如果要支援SEO,建議通過服務端來進行渲染元件);第一次載入首頁耗時相對長一些;不可以使用瀏覽器的導航按鈕需要自行實現前進、後退。

11.怎麼定義 vue-router 的動態路由? 怎麼獲取傳過來的值
答:在 router 目錄下的 index.js 檔案中,對 path 屬性加上 /:id,使用 router 物件的 params.id 獲取。

Vue面試題-2

1.什麼是vue的生命週期?

Vue例項從建立到銷燬的過程,就是生命週期。也就是從開始建立、初始化資料、編譯模板、掛載DOM->渲染、更新->渲染、解除安裝等一系列過程,我們稱這是Vue的生命週期。

2.vue生命週期的作用是什麼?

它的生命週期中有多個事件鉤子,讓我們在控制整個vue例項的過程時更容易形成好的邏輯。

3.Vue生命週期總共有幾個階段?

它可以總共分為8個階段:建立前/後,載入前/後,更新前/後,銷燬前/銷燬後

4.第一次頁面載入會觸發那幾個鉤子?

第一次頁面載入時會觸發beforeCreate,created,beforeMount,mounted

5.DOM渲染在哪個週期中就已經完成?

DOM渲染在mounted中就已經完成了

6.生命週期鉤子的一些使用方法:

1.beforecreate:可以在加個loading事件,在載入例項是觸發
2.created:初始化完成時的事件寫在這裡,如在這結束loading事件,非同步請求也適宜在這裡呼叫
3.mounted:掛載元素,獲取到dom節點
4.updated:如果對資料統一處理,在這裡寫上相應函式
5.beforeDestroy:可以一個確認停止事件的確認框
6.nextTick:更新資料後立即操作dom

7.v-show與v-if的區別

v-show是css切換,v-if是完整的銷燬和重新建立
使用頻繁切換時用v-show,執行時較少改變時用v-if
V-if=’false’v-if是條件渲染,當false的時候不會渲染
使用v-if的時候,如果值為false,那麼頁面將不會有這個html標籤生成
v-show則是不管值是為true還是false,html元素都會存在,只是css中的display顯示或隱藏
v-show 僅僅控制元素的顯示方式,將 display 屬性在 block 和 none 來回切換;而v-if會控制這個 DOM 節點的存在與否。當我們需要經常切換某個元素的顯示/隱藏時,使用v-show會更加節省效能上的開銷;當只需要一次顯示或隱藏時,使用v-if更加合理。

8.開發中常用的指令有哪些?

v-model:一般用在表達輸入,很輕鬆的實現表單控制元件和資料的雙向繫結
v-html:更新元素的innerHTML
v-show與v-if:條件渲染,注意二者區別
v-on:click:可以簡寫為@click,@繫結一個事件。如果事件觸發了,就可以指定事件的處理函式
v-for:基於源資料多次渲染元素或模板
v-bind:當表示式的值改變時,將其產生的連帶影響,響應式地作用於DOM語法
v-bind:title=”msg”簡寫:title=“msg”

9.繫結class的陣列用法

1.物件方法v-bind:class="{'orange':isRipe, 'green':isNotRipe}2.陣列方法v-bind:class="[class1,class2]"
3.行內v-bind:style="{color:color,fontSize:fontSize+'px'}

10.路由跳轉方式

1.router-link標籤會渲染為標籤,咋填template中的跳轉都是這種;
2.另一種是編輯是導航,也就是通過js跳轉比如router.push(’/home’)

11.MVVM

M-model,model代表資料模型,也可以在model中定義資料修改和操作的業務邏輯

V-view,view代表UI元件,它負責將資料模型轉化為UI展現出來

VM-viewmodel,viewmodel監聽模型資料的改變和控制檢視行為、處理使用者互動,簡單理解就是一個同步view和model的物件,連線model和view

12.computed和watch有什麼區別

computed

computed是計算屬性,也就是計算值,它更多用於計算值的場景
computed具有快取性,computed的值在getter執行後是會快取的,只有在它依賴的屬性值改變之後,下一次獲取computed的值時重新呼叫對應的getter來計算
computed適用於計算比較消耗效能的計算場景

watch

watch更多的是[觀察]的作用,類似於某些資料的監聽回撥,用於觀察props $emit或者本元件的值,當資料變化時來執行回撥進行後續操作
無快取性,頁面重新渲染時值不變化也會執行

小結

當我們要進行數值計算,而且依賴於其他資料,那麼把這個資料設計為computed
如果你需要在某個資料變化時做一些事情,使用watch來觀察這個資料變化。

13.vue元件的scoped屬性的作用

在style標籤上新增scoped屬性,以表示它的樣式作用於當下的模組,很好的實現了樣式私有化的目的;
但是也得慎用:樣式不易(可)修改,而很多時候,我們是需要對公共元件的樣式做微調的;

解決辦法:

①:使用混合型的css樣式:(混合使用全域性跟本地的樣式)

14.vue是漸進式的框架的理解:(主張最少,沒有多做職責之外的事)

Vue的核心的功能,是一個檢視模板引擎,但這不是說Vue就不能成為一個框架。如下圖所示,這裡包含了Vue的所有部件,在宣告式渲染(檢視模板引擎)的基礎上,我們可以通過新增元件系統、客戶端路由、大規模狀態管理來構建一個完整的框架。更重要的是,這些功能相互獨立,你可以在核心功能的基礎上任意選用其他的部件,不一定要全部整合在一起。可以看到,所說的“漸進式”,其實就是Vue的使用方式,同時也體現了Vue的設計的理念
在我看來,漸進式代表的含義是:主張最少。檢視模板引擎
每個框架都不可避免會有自己的一些特點,從而會對使用者有一定的要求,這些要求就是主張,主張有強有弱,它的強勢程度會影響在業務開發中的使用方式。
比如說,Angular,它兩個版本都是強主張的,如果你用它,必須接受以下東西:
必須使用它的模組機制- 必須使用它的依賴注入- 必須使用它的特殊形式定義元件(這一點每個檢視框架都有,難以避免)
所以Angular是帶有比較強的排它性的,如果你的應用不是從頭開始,而是要不斷考慮是否跟其他東西整合,這些主張會帶來一些困擾。
Vue可能有些方面是不如React,不如Angular,但它是漸進的,沒有強主張,你可以在原有大系統的上面,把一兩個元件改用它實現,當jQuery用;也可以整個用它全家桶開發,當Angular用;還可以用它的檢視,搭配你自己設計的整個下層用。也可以函式式,都可以,它只是個輕量檢視而已,只做了自己該做的事,沒有做不該做的事,僅此而已。
漸進式的含義,我的理解是:沒有多做職責之外的事。

15.vue.js的兩個核心是什麼(資料驅動、元件系統。)

資料驅動:Object.defineProperty和儲存器屬性: getter和setter(所以只相容IE9及以上版本),可稱為基於依賴收集的觀測機制,核心是VM,即ViewModel,保證資料和檢視的一致性。
元件系統:點此檢視

16.vue常用修飾符

修飾符分為:一般修飾符,事件修身符,按鍵、系統
①一般修飾符:
.lazy:v-model 在每次 input 事件觸發後將輸入框的值與資料進行同步 。你可以新增 lazy 修飾符,從而轉變為使用 change 事件進行同步

<input v-model.lazy="msg" >  

.number

<input v-model.number="age" type="number">

.trim

1.如果要自動過濾使用者輸入的首尾空白字元 <input v-model.trim='trim'>

② 事件修飾符

<a v-on:click.stop="doThis"></a><!-- 阻止單擊事件繼續傳播 -->

<form v-on:submit.prevent="onSubmit"></form> <!-- 提交事件不再過載頁面 -->

<a v-on:click.stop.prevent="doThat"></a> <!-- 修飾符可以串聯 -->

<form v-on:submit.prevent></form>   <!-- 只有修飾符 -->

<div v-on:click.capture="doThis">...</div>   <!-- 新增事件監聽器時使用事件捕獲模式 --> <!-- 即元素自身觸發的事件先在此處處理,然後才交由內部元素進行處理 -->

<div v-on:click.self="doThat">...</div>  <!-- 只當在 event.target 是當前元素自身時觸發處理函式 --> <!-- 即事件不是從內部元素觸發的 -->

<a v-on:click.once="doThis"></a> <!-- 點選事件將只會觸發一次 -->

③按鍵修飾符
全部的按鍵別名:

.enter
.tab
.delete (捕獲“刪除”和“退格”鍵)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
<input v-on:keyup.enter="submit"> 或者 <input @keyup.enter="submit">

④系統修飾鍵 (可以用如下修飾符來實現僅在按下相應按鍵時才觸發滑鼠或鍵盤事件的監聽器。)

.ctrl
.alt
.shift
.meta
<input @keyup.alt.67="clear"> 或者 <div @click.ctrl="doSomething">Do something</div><!-- Ctrl + Click -->

17.v-on可以監聽多個方法嗎?(可以的)

一個元素繫結多個事件的兩種寫法,一個事件繫結多個函式的兩種寫法,修飾符的使用。

<a style="cursor:default" v-on='{click:DoSomething,mouseleave:MouseLeave}'>doSomething</a>

在method方法裡面分別寫兩個時事件;

<button @click="a(),b()">點我ab</button>

18.vue事件中如何使用event物件

<button @click="Event($event)">事件物件</button>

19.比如你想讓一個dom元素顯示,然後下一步去獲取這個元素的offsetWidth,最後你獲取到的會是0。

因為你改變資料把show變成true,元素並不會立即顯示,理所當然也不會獲取到動態寬度。
正確的做法是先把元素show出來,在$nextTick去執行獲取寬度的操作,不知道這樣說會不會好理解一點。

openSubmenu() {
this.show = true //獲取不到寬度
this.$nextTick(() => //這裡才可以 let w = this.$refs.submenu.offsetWidth;
})
}

20.Vue 元件中 data 為什麼必須是函式

vue元件中data值不能為物件,因為物件是引用型別,元件可能會被多個例項同時引用。
如果data值為物件,將導致多個例項共享一個物件,其中一個元件改變data屬性值,其它例項也會受到影響。

21.vue中子元件呼叫父元件的方法

第一種方法是直接在子元件中通過this. p a r e n t . e v e n t 來 調 用 父 組 件 的 方 法 第 二 種 方 法 是 在 子 組 件 裡 用 parent.event來呼叫父元件的方法 第二種方法是在子元件裡用 parent.event調emit向父元件觸發一個事件,父元件監聽這個事件就行了。
第三種都可以實現子元件呼叫父元件的方法,

<template>
  <div>
    <button @click="childMethod()">點選</button>
  </div>
</template>
<script>
  export default {
    props: {
      fatherMethod: {
        type: Function,
        default: null
      }
    },
    methods: {
      childMethod() {
        if (this.fatherMethod) {
          this.fatherMethod();
        }
      }
    }
  };
</script>

22.vue中 keep-alive 元件的作用

keep-alive 是 Vue 內建的一個元件,可以使被包含的元件保留狀態,或避免重新渲染。

<keep-alive>
  <component>
    <!-- 該元件將被快取! -->
  </component>
</keep-alive>
如果只想 router-view 裡面某個元件被快取


export default [
  {
    path: '/',
    name: 'home',
    component: Home,
    meta: {
      keepAlive: true // 需要被快取
    }
  }, {
    path: '/:id',
    name: 'edit',
    component: Edit,
    meta: {
      keepAlive: false // 不需要被快取
    }
  }
]
<keep-alive>
    <router-view v-if="$route.meta.keepAlive">
        <!-- 這裡是會被快取的檢視元件,比如 Home! -->
    </router-view>
</keep-alive>
 
<router-view v-if="!$route.meta.keepAlive">
    <!-- 這裡是不被快取的檢視元件,比如 Edit! -->
</router-view>

23.vue中如何編寫可複用的元件?

去這裡看一下blog.csdn.net

①建立元件頁面eg Toast.vue;
②用Vue.extend()擴充套件一個元件構造器,再通過例項化元件構造器,就可創造出可複用的元件
③將toast元件掛載到新建立的div上;
④把toast元件的dom新增到body裡;
⑤修改優化達到動態控制頁面顯示文字跟顯示時間;

import Vue from 'vue'; 
import Toast from '@/components/Toast';     //引入元件
let ToastConstructor  = Vue.extend(Toast) // 返回一個“擴充套件例項構造器”
 
let myToast = (text,duration)=>{
    let toastDom = new ToastConstructor({
        el:document.createElement('div')    //將toast元件掛載到新建立的div上
    })
    document.body.appendChild( toastDom.$el )   //把toast元件的dom新增到body裡
    
    toastDom.text = text;
    toastDom.duration = duration;
 
    // 在指定 duration 之後讓 toast消失
    setTimeout(()=>{
        toastDom.isShow = false;  
    }, toastDom.duration);
}
export default myToast;

24.什麼是vue生命週期和生命週期鉤子函式?

beforecreated:在例項初始化之後,el 和 data 並未初始化(這個時期,this變數還不能使用,在data下的資料,和methods下的方法,watcher中的事件都不能獲得到;)
created:完成了 data 資料的初始化,el沒有(這個時候可以操作vue例項中的資料和各種方法,但是還不能對"dom"節點進行操作;)
beforeMount:完成了 el 和 data 初始化 //這裡的el是虛擬的dom;
mounted :完成掛載,在這發起後端請求,拿回資料,配合路由鉤子做一些事情(掛載完畢,這時dom節點被渲染到文件內,一些需要dom的操作在此時才能正常進行)
beforeUpdate:是指view層資料變化前,不是data中的資料改變前觸發;
update:是指view層的資料變化之後,
beforeDestory: 你確認刪除XX嗎?
destoryed :當前元件已被刪除,清空相關內容
A、什麼是vue生命週期?
Vue 例項從建立到銷燬的過程,就是生命週期。也就是從開始建立、初始化資料、編譯模板、掛載Dom→渲染、更新→渲染、解除安裝等一系列過程,我們稱這是 Vue 的生命週期。
B、vue生命週期的作用是什麼?
它的生命週期有多個事件鉤子,讓我們在控制整個Vue例項的過程時更容易形成好的邏輯。
C、vue生命週期總共有幾個階段?
它可以總共分為8個階段:建立前/後, 載入前/後,更新前/後,銷燬前/銷燬後
D、第一次頁面載入會觸發哪幾個鉤子?
第一次頁面載入時會觸發 beforeCreate, created, beforeMount, mounted 這幾個鉤子
E、DOM 渲染在 哪個週期中就已經完成?
DOM 渲染在 mounted 中就已經完成了。
F、簡單描述每個週期具體適合哪些場景?
生命週期鉤子的一些使用方法: beforecreate : 可以在這加個loading事件,在載入例項時觸發 created : 初始化完成時的事件寫在這裡,如在這結束loading事件,非同步請求也適宜在這裡呼叫 mounted : 掛載元素,獲取到DOM節點 updated : 如果對資料統一處理,在這裡寫上相應函式 beforeDestroy : 可以做一個確認停止事件的確認框 nextTick : 更新資料後立即操作dom;

25.vue更新陣列時觸發檢視更新的方法

Vue.set    ==========Vue.set(target,key,value)這個方法主要是用於避開vue不能檢測屬性被新增的限制
Vue.set(array, indexOfItem, newValue)//indexOfItem指的索引
this.array.$set(indexOfItem, newValue)
Vue.set(obj, keyOfItem, newValue)
this.obj.$set(keyOfItem, newValue)
Vue.delete   這個方法主要用於避開vue不能檢測到屬性被刪除;

Vue.delete(array, indexOfItem)
this.array.$delete(indexOfItem)
Vue.delete(obj, keyOfItem)
this.obj.$delete(keyOfItem)

26.webpack的編譯原理

webpack面試題彙總www.jianshu.com圖示

webpack的作用

①、依賴管理:方便引用第三方模組、讓模組更容易複用,避免全域性注入導致的衝突、避免重複載入或者載入不需要的模組。會一層一層的讀取依賴的模組,新增不同的入口;同時,不會重複打包依賴的模組。
②、合併程式碼:把各個分散的模組集中打包成大檔案,減少HTTP的請求連結數,配合UglifyJS(壓縮程式碼)可以減少、優化程式碼的體積。
③、各路外掛:統一處理引入的外掛,babel編譯ES6檔案,TypeScript,eslint 可以檢查編譯期的錯誤。
**一句話總結:**webpack 的作用就是處理依賴,模組化,打包壓縮檔案,管理外掛。
一切皆為模組,由於webpack只支援js檔案,所以需要用loader 轉換為webpack支援的模組,其中plugin 用於擴張webpack 的功能,在webpack構建生命週期的過程中,在合適的時機做了合適的事情。

webpack怎麼工作的過程

①解析配置引數,合併從shell(npm install 類似的命令)和webpack.config.js檔案的配置資訊,輸出最終的配置資訊;
②註冊配置中的外掛,讓外掛監聽webpack構建生命週期中的事件節點,做出對應的反應;
③解析配置檔案中的entry入口檔案,並找出每個檔案依賴的檔案,遞迴下去;
④在遞迴每個檔案的過程中,根據檔案型別和配置檔案中的loader找出對應的loader對檔案進行轉換;
⑤遞迴結束後得到每個檔案最終的結果,根據entry 配置生成程式碼chunk(打包之後的名字);
⑥輸出所以chunk 到檔案系統。

27.vue等單頁面應用及其優缺點

缺點:

不支援低版本的瀏覽器,最低只支援到IE9;
不利於SEO的優化(如果要支援SEO,建議通過服務端來進行渲染元件);
第一次載入首頁耗時相對長一些;
不可以使用瀏覽器的導航按鈕需要自行實現前進、後退。

優點:

無重新整理體驗,提升了使用者體驗;
前端開發不再以頁面為單位,更多地採用元件化的思想,程式碼結構和組織方式更加規範化,便於修改和調整;
API 共享,同一套後端程式程式碼不用修改就可以用於Web介面、手機、平板等多種客戶端
使用者體驗好、快,內容的改變不需要重新載入整個頁面。

28.什麼是vue的計算屬性computed

計算屬性是需要複雜的邏輯,可以用方法method代替

computed:{
    totalPrice(){
      return (this.good.price*this.good.count)*this.discount+this.deliver;
    }
  }

29.vue-cli提供的幾種腳手架模板

vue-cli 的腳手架專案模板有browserify 和 webpack;

30.元件中傳遞資料?

props:export default {
props: {

message: String //定義傳值的型別<br>

},


//或者props:["message"]

data: {}

父元件呼叫子元件的方法:父元件   this.$refs.yeluosen.childMethod()


子元件向父元件傳值並呼叫方法 $emit


元件之間:bus==$emit+$on

31.vue-router實現路由懶載入( 動態載入路由 )

img

32.vue-router 的導航鉤子,主要用來作用是攔截導航,讓他完成跳轉或取消。

**全域性的:**前置守衛、後置鉤子(beforeEach,afterEach)beforeResolve
**單個路由獨享的:**beforeEnter
元件級的: beforeRouteEnter(不能獲取元件例項 this)、beforeRouteUpdate、beforeRouteLeave
這是因為在執行路由鉤子函式beforRouteEnter時候,元件還沒有被建立出來;
先執行beforRouteEnter,再執行元件週期鉤子函式beforeCreate,可以通過 next 獲取元件的例項物件,如:next( (vm)=>{} ),引數vm就是元件的例項化物件。

33.完整的 vue-router 導航解析流程

1.導航被觸發;
2.在失活的元件裡呼叫beforeRouteLeave守衛;
3.呼叫全域性beforeEach守衛;
4.在複用元件裡呼叫beforeRouteUpdate守衛;
5.呼叫路由配置裡的beforeEnter守衛;
6.解析非同步路由元件;
7.在被啟用的元件裡呼叫beforeRouteEnter守衛;
8.呼叫全域性beforeResolve守衛;
9.導航被確認;
10…呼叫全域性的afterEach鉤子;
11.DOM更新;
12.用建立好的例項呼叫beforeRouteEnter守衛中傳給next的回撥函式。

34.vue-router如何響應 路由引數 的變化?

原來的元件例項會被複用。這也意味著元件的生命週期鉤子不會再被呼叫。你可以簡單地 watch (監測變化) $route 物件:

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 對路由變化作出響應...
    }
  }
}


const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 對路由變化作出響應...
    }
  }
}

35.vue-router的幾種例項方法以及引數傳遞

name傳遞
to來傳遞
採用url傳參

36.is的用法(用於動態元件且基於 DOM 內模板的限制來工作。)

is用來動態切換元件,DOM模板解析

<table> <tr is="my-row"></tr> </table>

37.vuex是什麼?怎麼使用?哪種功能場景使用它?

是什麼:vue框架中狀態管理:有五種,分別是 State、 Getter、Mutation 、Action、 Module
使用:新建一個目錄store,
場景:單頁應用中,元件之間的狀態。音樂播放、登入狀態、加入購物車

vuex的State特性
A、Vuex就是一個倉庫,倉庫裡面放了很多物件。其中state就是資料來源存放地,對應於一般Vue物件裡面的data
B、state裡面存放的資料是響應式的,Vue元件從store中讀取資料,若是store中的資料發生改變,依賴這個資料的元件也會發生更新
C、它通過mapState把全域性的 state 和 getters 對映到當前元件的 computed 計算屬性中

vuex的Getter特性
A、getters 可以對State進行計算操作,它就是Store的計算屬性
B、 雖然在元件內也可以做計算屬性,但是getters 可以在多元件之間複用
C、 如果一個狀態只在一個元件內使用,是可以不用getters

vuex的Mutation特性
改變store中state狀態的唯一方法就是提交mutation,就很類似事件。
每個mutation都有一個字串型別的事件型別和一個回撥函式,我們需要改變state的值就要在回撥函式中改變。
我們要執行這個回撥函式,那麼我們需要執行一個相應的呼叫方法:store.commit。

Action 類似於 mutation,不同在於:Action 提交的是 mutation,而不是直接變更狀態;
Action 可以包含任意非同步操作,Action 函式接受一個與 store 例項具有相同方法和屬性的 context 物件,
因此你可以呼叫 context.commit 提交一個 mutation,
或者通過 context.state 和 context.getters 來獲取 state 和 getters。
Action 通過 store.dispatch 方法觸發:eg。
store.dispatch('increment')

vuex的module特性
Module其實只是解決了當state中很複雜臃腫的時候,module可以將store分割成模組,
每個模組中擁有自己的state、mutation、action和getter

相關文章