天天看點

2017前端面試題總結

2017前端面試題總結

1:為何選擇前端這個方向和對前端的了解

為什麼:

第一的話就是對前端很感興趣,之前也接觸過其他的語言,但是直到接觸到前端才發現真的有興趣做下去,興趣是一個人最好的老師,

第二的話前端很有前途,像現在nodejs,rn,微信小程式這類工具和架構可以讓前端進行後端和移動開發,是以我覺得前端的前途會更多一點。

了解:

首先前端工程師最核心的技能還是:Html、CSS、JS。前端負責的是使用者可以看到的部分,是以也是最接近使用者的工程師。同時在産品研發流程中前端要同時與産品、設計、後端等很多人合作。

2:Vue雙向資料綁定的實作

vue.js 則是采用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出消息給訂閱者(文本節點則是作為訂閱者),在收到消息後執行相應的更新操作。

compile主要做的事情是解析模闆指令,将模闆中的變量替換成資料,然後初始化渲染頁面視圖,并将每個指令對應的節點綁定更新函數,添加監聽資料的訂閱者,一旦資料有變動,收到通知,更新視圖

MVVM作為資料綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model資料變化,通過Compile來解析編譯模闆指令,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達到資料變化 -> 視圖更新;視圖互動變化(input) -> 資料model變更的雙向綁定效果。

AngularJS 采用“髒值檢測”的方式,資料發生變更後,對于所有的資料和視圖的綁定關系進行一次檢測,識别是否有資料發生了改變。

3:react和vue有哪些不同 說說你對這兩個架構的看法

都用了virtual dom的方式, 性能都很好

ui上都是元件化的寫法,開發效率很高

vue是雙向資料綁定,react是單項資料綁定,當工程規模比較大時雙向資料綁定會很難維護

vue适合不會持續的 小型的web應用,使用vue.js能帶來短期内較高的開發效率. 否則采用react

4:let和const的差別

let聲明的變量可以改變,值和類型都可以改變,沒有限制。

const聲明的變量不得改變值

5:平時用了es6的哪些特性,體驗如何 和es5有什麼不同

let const關鍵字 箭頭函數 字元串模闆 class類 子產品化 promise

es5 require react.createclass

6:浏覽器原生支援module嗎,如果支援,會帶來哪些便利

不支援

7:介紹一下你對webpack的了解,和gulp有什麼不同

Webpack是子產品打包工具,他會分析子產品間的依賴關系,然後使用loaders處理它們,最後生成一個優化并且合并後的靜态資源。

gulp是前端自動化工具 能夠優化前端工作流程,比如檔案合并壓縮

8:webpack打包速度慢,你覺得可能的原因是什麼,該如何解決

子產品太多

Webpack 可以配置 externals 來将依賴的庫指向全局變量,進而不再打包這個庫 或者dllplugin

webpack-parallel-uglify-plugin 并行壓縮

CommonsChunkPlugin提取公共的子產品

happypack 多程序建構

9:http響應中content-type包含哪些内容

請求中的消息主體是用何種方式編碼

application/x-www-form-urlencoded

這是最常見的 POST 送出資料的方式 按照 key1=val1&key2=val2 的方式進行編碼

application/json

告訴服務端消息主體是序列化後的 JSON 字元串

10:浏覽器緩存有哪些,通常緩存有哪幾種方式

強緩存 強緩存如果命中,浏覽器直接從自己的緩存中讀取資源,不會發請求到伺服器。

協商緩存 當強緩存沒有命中的時候,浏覽器一定會發送一個請求到伺服器,通過伺服器端依據資源的另外一些http header驗證這個資源是否命中協商緩存,如果協商緩存命中,伺服器會将這個請求傳回(304),若未命中請求,則将資源傳回用戶端,并更新本地緩存資料(200)。

HTTP頭資訊控制緩存

Expires(強緩存)+過期時間 Expires是HTTP1.0提出的一個表示資源過期時間的header,它描述的是一個絕對時間

Cache-control(強緩存) 描述的是一個相對時間,在進行緩存命中的時候,都是利用用戶端時間進行判斷 管理更有效,安全一些 Cache-Control: max-age=3600

服務端傳回頭Last-Modified/ 用戶端請求頭If-Modified-Since(協商緩存) 标示這個響應資源的最後修改時間。Last-Modified是伺服器相應給用戶端的,If-Modified-Sinces是用戶端發給伺服器,伺服器判斷這個緩存時間是否是最新的,是的話拿緩存。

服務端傳回頭Etag/用戶端請求頭If-None-Match(協商緩存) etag和last-modified類似,他是發送一個字元串來辨別版本。

強緩存不請求伺服器,用戶端判斷 、協商緩存要請求伺服器

11:如何取出一個數組裡的圖檔并按順序顯示出來

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

function loadImage(imgList,callback){

if(! . i s A r r a y ( i m g L i s t ) ∣ ∣ ! .isArray(imgList) || ! .isArray(imgList)∣∣!.isFunction(callback)) return ;

var imageData = [] ;

$.each(imgList, function(i,src){

var img = new Image() ;

img.onload = function(){

$(imageData.shift()).appendTo(“body”) ;

if(!imageData.length){

callback() ;

return ;

}

this.onload = null ;

} ;

img.src= src ;

imageData.push(img) ;

}) ;

} ;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

async function loadImgs(imgList, cb) {

console.log("start")
for( var i =0; i<imgList.length; i++) {
    await imgLoader(imgList[i], i);
    console.log("finish"+i)
}
cb();
           

}

async function imgLoader(url, num){

return new Promise((resolve, reject) => {

console.log(“request”+num)

setTimeout(resolve, 1000);
    // let img = new Image();
    // img.onload = () => resolve(img);
    // img.onerror = reject;

    console.log("return"+num)
})
           

}

loadImgs([“xxx/a.png”,“xxx/b.png”],function() {

console.log(“開始幹活”);

})

12:平時是怎麼學新技術的

伯樂線上 infoq 掘金 簡書 慕課網

13:Node,Koa用的怎麼樣

koa是一個相對于express來說,更小,更健壯,更富表現力的Web架構,不用寫回調

koa是從第一個中間件開始執行,遇到next進入下一個中間件,一直執行到最後一個中間件,在逆序

async await文法的支援

14:使用子產品化加載時,子產品加載的順序是怎樣的,如果不知道,根據已有的知識,你覺得順序應該是怎麼樣的

commonjs 同步 順序執行

AMD 提前加載,不管是否調用子產品,先解析所有子產品 requirejs 速度快 有可能浪費資源

CMD 提前加載,在真正需要使用(依賴)子產品時才解析該子產品 seajs 按需解析 性能比AMD差

15: 介紹一下閉包和閉包常用場景

閉包是指有權通路另一個函數作用域中的變量的函數. 建立閉包常見方式,就是在一個函數内部建立另一個函數.
本質上,閉包就是将函數内部和函數外部連接配接起來的一座橋梁。
           

應用場景 設定私有變量和方法讓這些變量的值始終保持在記憶體中還有讀取函數内部變量。

不适合場景:傳回閉包的函數是個非常大的函數

閉包的缺點就是常駐記憶體,會增大記憶體使用量,使用不當很容易造成記憶體洩露。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function f1(){

var n=999;

function f2(){

    alert(n);

  }

return f2;

}

var result=f1();

result(); // 999

16: 為什麼會出現閉包這種東西,解決了什麼問題

受JavaScript鍊式作用域結構的影響,父級變量中無法通路到子級的變量值,為了解決這個問題,才使用閉包這個概念

17: 介紹一下你所了解的作用域鍊,作用域鍊的盡頭是什麼,為什麼

每一個函數都有一個作用域,比如我們建立了一個函數,函數裡面又包含了一個函數,那麼現在 就有三個作用域,這樣就形成了一個作用域鍊。

作用域的特點就是,先在自己的變量範圍中查找,如果找不到,就會沿着作用域鍊往上找。

18: 一個Ajax建立的過程是怎樣的,主要用到哪些狀态碼

ajax:在不切換頁面的情況下完成異步的HTTP請求

(1)建立XMLHttpRequest對象,也就是建立一個異步調用對象.

(2)建立一個新的HTTP請求,并指定該HTTP請求的方法、URL及驗證資訊.

(3)設定響應HTTP請求狀态變化的函數.

(4)發送HTTP請求.

(5)擷取異步調用傳回的資料.

(6)使用JavaScript和DOM實作局部重新整理.

1

2

3

4

5

6

7

8

9

10

11

12

13

var xmlHttp = new XMLHttpRequest();

xmlHttp.open(‘GET’,‘demo.php’,‘true’);

xmlHttp.send()

xmlHttp.onreadystatechange = function(){

if(xmlHttp.readyState === 4 & xmlHttp.status === 200){

  }
           

}

使用promise封裝

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

function getJSON(url) {

return new Promise(function(resolve, reject) {

var XHR = new XMLHttpRequest();

XHR.open(‘GET’, url, true);

XHR.send();

XHR.onreadystatechange = function() { 
        if (XHR.readyState == 4) { 
            if (XHR.status == 200) { 
                try { 
                    var response = JSON.parse(XHR.responseText); 
                    resolve(response); 
                } catch (e) { 
                    reject(e); 
                } 
            } else { 
                reject(new Error(XHR.statusText)); 
            } 
        } 
    } 
}) 
           

}

getJSON(url).then(res => console.log(res));

目前狀态readystate

0 代表未初始化。 還沒有調用 open 方法

1 代表正在加載。 open 方法已被調用,但 send 方法還沒有被調用

2 代表已加載完畢。send 已被調用。請求已經開始

3 代表互動中。伺服器正在發送響應

4 代表完成。響應發送完畢

常用狀态碼status

404 沒找到頁面(not found)

403 禁止通路(forbidden)

500 内部伺服器出錯(internal service error)

200 一切正常(ok)

304 沒有被修改(not modified)(伺服器傳回304狀态,表示源檔案沒有被修改)

19: 說說你還知道的其他狀态碼,狀态碼的存在解決了什麼問題

302/307  臨時重定向

301 永久重定向

借助狀态碼,使用者可以知道伺服器端是正常處理了請求,還是出現了什麼錯誤

20: 知道語義化嗎?說說你了解的語義化,如果是你,平時會怎麼做來保證語義化

像html5的新的标簽header,footer,section等就是語義化

一方面,語義化就是讓計算機能夠快速的讀懂内容,高效的處理資訊,可以對搜尋引擎更友好。

另一方面,便于與他人的協作,他人通過讀代碼就可以了解你網頁标簽的意義。

21: 說說content-box和border-box,為什麼看起來content-box更合理,但是還是經常使用border-box

content-box 是W3C的标準盒模型 元素寬度=内容寬度+padding+border

border-box 是ie的怪異盒模型 他的元素寬度等于内容寬度 内容寬度包含了padding和border

比如有時候在元素基礎上添加内距padding或border會将布局撐破 但是使用border-box就可以輕松完成

22:介紹一下HTML5的新特性

新的DOCTYPE聲明  <!DOCTYPE html> 
完全支援css3
video和audio
本地存儲
語義化标簽
canvas
新事件 如ondrag onresize
           

23:對自己未來的規劃是怎樣的

對于剛畢業的人來說,前兩年是很重要的,先打好基礎,多提升js能力。三至四年在提升JS能力的同時,開始要往多方面發展,前端工程師遠遠不僅是JS而已。制作一個性能高、互動好、視覺美的頁面,需要從前端架構選型、架構設計、建構工具,到後端通信機制、設計與互動、網絡和浏覽器優化等各方面的知識。一專多長才是前端工程師的終極目标。

24: 在一個UI李有10個li,實作點選對應的li,輸出對應的下标

1

2

3

4

5

6

7

8

var lis = querySelectorAll(‘li’)

for(var i=0;i<10;i++){

lis[i].onclick = (function(a) {

return function() {

alert(a)

}

})(i)

}

事件委托

利用冒泡的原理,把事件加到父級上,觸發執行效果。

1.可以大量節省記憶體占用,減少事件注冊。

2.可以友善地動态添加和修改元素,不需要因為元素的改動而修改事件綁定。

1

2

3

4

5

6

7

8

9

10

11

12

13

var ul = document.querySelector(‘ul’);

var list = document.querySelectorAll(‘ul li’);

ul.addEventListener(‘click’, function(ev){

var ev = ev || window.event;

var target = ev.target || ev.srcElemnt;

for(var i = 0, len = list.length; i < len; i++){ 
    if(list[i] == target){ 
        alert(i + "----" + target.innerHTML); 
    } 
} 
           

});

25:實作三個DIV等分排布在一行(考察border-box)

1.設定border-box width33.3%

2.flexbox flex:1

26: 說說你知道JavaScript的記憶體回收機制

垃圾回收器會每隔一段時間找出那些不再使用的記憶體,然後為其釋放記憶體。

一般使用标記清除方法 當變量進入環境标記為進入環境,離開環境标記為離開環境

還有引用計數方法

堆棧

stack為自動配置設定的記憶體空間,它由系統自動釋放;而heap則是動态配置設定的記憶體,大小不定也不會自動釋放。

基本資料類型存放在棧中

引用類型 存放在堆記憶體中,首先從棧中獲得該對象的位址指針,然後再從堆記憶體中取得所需的資料

27函數防抖和函數節流

函數防抖是指頻繁觸發的情況下,隻有足夠的空閑時間,才執行代碼一次

函數防抖的要點,也是需要一個setTimeout來輔助實作。延遲執行需要跑的代碼。

如果方法多次觸發,則把上次記錄的延遲執行代碼用clearTimeout清掉,重新開始。

如果計時完畢,沒有方法進來通路觸發,則執行代碼。

1

2

3

4

5

6

7

8

//函數防抖

var timer = false

document.getElementById(“debounce”).onScroll = function() {

clearTimeout(timer)

timer = setTimeout(function(){

console.log(‘函數防抖’)

}, 300)

}

函數節流是指一定時間内js方法隻跑一次

函數節流的要點是,聲明一個變量當标志位,記錄目前代碼是否在執行。

如果空閑,則可以正常觸發方法執行。

如果代碼正在執行,則取消這次方法執行,直接return。

1

2

3

4

5

6

7

8

9

10

11

12

//函數節流

var canScroll = true;

document.getElementById(‘throttle’).onScroll = function() {

if (!canScroll) {

return;

}

canScroll = false;

setTimeout(function(){

console.log(‘函數節流’);

canScroll = true;

},300)

}

28:程式設計實作輸出一個數組中第N大的資料

29.實作兩欄布局有哪些方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

*{margin:0; padding: 0;}

html,body{

height: 100%;/高度百分百顯示/

}

#left{

width: 300px;

height: 100%;

background-color: #ccc;

float: left;

}

#right{

height: 100%;

margin-left: 300px;

background-color: #eee;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

*{margin:0; padding: 0;}

html,body{

height: 100%;/高度百分百顯示/

}

#left{

width: 300px;

height: 100%;

background-color: #ccc;

float: left;

}

#right{

height: 100%;

overflow:hidden;

background-color: #eee;

}

第二種方法,我利用的是建立一個新的BFC(塊級格式化上下文)來防止文字環繞的原理來實作的。BFC就是一個相對獨立的布局環境,它内部元素的布局不受外面布局的影響。它可以通過以下任何一種方式來建立:

float 的值不為 none

position 的值不為 static 或者 relative

display 的值為 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一個

overflow 的值不為 visible

第三種flex布局

30:設定width的flex元素,flex屬性值是多少

flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫

flex-grow屬性定義項目的放大比例,預設為0

flex-shrink屬性定義了項目的縮小比例,預設為1

flex-basis屬性定義了項目的固定空間

31get和post有什麼不同

get是從伺服器上擷取資料,post是向伺服器傳送資料

get請求可以将查詢字元串參數追加到url的末尾; post請求應該把資料作為請求的主體送出.

get請求資料有大小限制;post沒有

post比get安全性更高

32:cookie和session有什麼聯系和差別

cookie資料存放在客戶的浏覽器上,session資料放在伺服器上。

session比cookie更安全

單個cookie儲存的資料不能超過4K,很多浏覽器都限制一個站點最多儲存20個cookie。

一般用cookie來存儲sessionid

33:判斷連結清單是否有環

使用追趕的方法,設定兩個指針slow、fast,從頭指針開始,每次分别前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到NULL退出。

34:輸出二叉樹的最小深度

判斷左子樹或右子樹是否為空,若左子樹為空,則傳回右子樹的深度,反之傳回左子樹的深度,如果都不為空,則傳回左子樹和右子樹深度的最小值。

35: javaScript中的this是什麼,有什麼用,它的指向是什麼

全局代碼中的this 是指向全局對象

作為對象的方法調用時指向調用這個函數的對象。

作為構造函數指向新建立的對象

使用apply和call設定this

36寫一個快速排序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

var quickSort = function (arr){

if(arr.lenght <= 1) {

return arr;

}

var left = [];
   var right = [];
   var mid = arr.splice(Math.floor(arr.length/2), 1);

   for(var i=0;i<arr.length;i++){
         if(arr[i]<mid) {
             left.push(arr[i]);
        }
         if(arr[i]>mid) {
             right.push(arr[i]);
        }
      return quickSort(left).concat(mid, quickSort(right));
 }  
           

}

37怎麼實作從一個DIV左上角到右下角的移動,有哪些方法,都怎麼實作

改變left值為window寬度-div寬度 top值為window高度-div高度

jquery的animate方法

css3的transition

38: 簡單介紹一下promise,他解決了什麼問題

Promise,就是一個對象,用來傳遞異步操作的消息。有三種狀态:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失敗)。

有了 Promise 對象,就可以将異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。

39: 寫一個組合繼承

1

2

3

4

5

6

7

8

9

var Super = function(name){

this.name = name;

}

Super.prototype.func1 = function() { console.log(‘func1’); }

var Sub = function(name,age) {

Super.call(this, name);

this.age = age;

}

Sub.prototype = new Super();

40:深拷貝方案有哪些,手寫一個深拷貝

1

2

3

4

5

6

7

var clone = function(v) {

var o = v.constructor === Array ? [] : {};

for (var i in v) {

o[i] = typeof v[i] === “Object” ? clone(v[i]) : v[i];

}

return o;

}

41:判斷數組有哪些方法

a instanceof Array

a.constructor == Array

Object.prototype.toString.call(a) == [Object Array]

42: 跨域通信有哪些方案,各有什麼不同

JSONP:由于同源政策的限制,XmlHttpRequest隻允許請求目前源,script标簽沒有同源限制

通過動态

簡述原理與過程:首先在用戶端注冊一個callback, 然後把callback的名字傳給伺服器。此時,伺服器先生成一個function , function 名字就是傳遞上來的參數。最後将 json 資料直接以入參的方式,放置到 function 中,這樣就生成了一段 js 文法的文檔,傳回給用戶端。用戶端浏覽器,解析script标簽,并執行傳回的 javascript 文檔,此時資料作為參數,傳入到了用戶端預先定義好的 callback 函數裡

1

2

3

4

5

6

7

8

9

10

11

74.setTimeout,setInterval,requestAnimationFrame之間的差別

setInterval如果函數執行的時間很長的話,第二次的函數會放到隊列中,等函數執行完再執行第二次,導緻時間間隔發生錯誤。

而settimeout一定是在這個時間定時結束之後,它才會執行

requestAnimationFrame是為了做動畫專用的一個方法,這種方法對于dom節點的操作會比較頻繁。

75.webpack常用到哪些功能

設定入口 設定輸出目 設定loader extract-text-webpack-plugin将css從js代碼中抽出并合并 處理圖檔文字等功能 解析jsx解析bable

76.介紹sass

&定義變量 css嵌套 允許在代碼中使用算式 支援if判斷for循環

77.websocket和ajax輪詢

Websocket是HTML5中提出的新的協定,注意,這裡是協定,可以實作用戶端與伺服器端的通信,實作伺服器的推送功能。

其優點就是,隻要建立一次連接配接,就可以連續不斷的得到伺服器推送的消息,節省帶寬和伺服器端的壓力。

ajax輪詢模拟長連接配接就是每個一段時間(0.5s)就向伺服器發起ajax請求,查詢伺服器端是否有資料更新

其缺點顯而易見,每次都要建立HTTP連接配接,即使需要傳輸的資料非常少,是以這樣很浪費帶寬

78.tansition和margin的百分比根據什麼計算

transition是相對于自身,margin相對于參照物

79.冒泡排序、快速排序、去重、查找字元串最多值

1

2

3

4

5

6

7

8

9

10

11

12

13

//冒泡排序

var bubbleSort = function(arr) {

for (var i = 0; i < arr.length-1; i++) {

for (var j = i+1; j < arr.length; j++) {

if (arr[i]>arr[j]) {

var temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

}

}

return arr;

};

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

//快速排序

var quickSort = function(arr) {

if (arr.length <= 1) {

return arr;

}

var len = arr.length;

var midIndex = Math.floor(len/2);

var mid = arr.splice(midIndex,1);

var left = [];

var right = [];

for (var i = 0; i < arr.length; i++) {

if (arr[i] < mid) {

left.push(arr[i]);

} else {

right.push(arr[i]);

}

}

return quickSort(left).concat(mid,quickSort(right))

}

1

2

3

4

5

6

7

8

9

10

11

12

// 去重

var distinct = function(arr) {

var map = {};

var result = [];

for (var i = 0; i < arr.length; i++) {

if (!map[arr[i]]) {

map[arr[i]] = true;

result.push(arr[i]);

}

}

return result;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

//查找字元串中最多的值

var search = function(str) {

var json = {};

var max = 0;

var char;

for (var i = 0; i < str.length; i++) {

if (!json[str[i]]) {

json[str[i]]=1;

} else {

json[str[i]]++;

}

}

console.log(json);

for(var i in json){

if(json[i]>max){

max = json[i];

char = i;

}

}

console.log(max, char);

}

80.函數組合繼承

原型繼承、構造函數繼承、call aplly繼承

1

2

3

4

5

6

7

8

9

var Super = function(name){

this.name = name;

}

Super.prototype.func1 = function() { console.log(‘func1’); }

var Sub = function(name,age) {

Super.call(this, name);

this.age = age;

}

Sub.prototype = new Super();

81.事件綁定

1

2

3

4

5

6

7

8

9

var addEvent = function(e, type, handler, capture ) {

if (e.addEventListener) {

e.addEventListener(type, handler, capture);

} else if (e.attachEvent) {

e.attachEvent(‘on’+type, handler);

} else {

e[‘on’+type] = handler;

}

}

82.淺克隆和深度克隆

1

2

3

4

5

6

7

8

9

//淺克隆

function extendCopy§ {

    var c = {};

    for (var i in p) {

      c[i] = p[i];

    }

    c.uber = p;

    return c;

 }

1

1

2

3

4

5

6

7

8

//深度克隆

var clone = function(v) {

var o = v.constructor === Array ? [] : {};

for (var i in v) {

o[i] = typeof v[i] === “Object” ? clone(v[i]) : v[i];

}

return o;

}

es6的深度克隆

通過Object.getPrototypeOf函數得到obj被克隆函數的原型上的屬性,然後通過Object.assign實作深度克隆。

1

2

3

4

const deepClone=(obj)=>{

var proto=Object.getPrototypeOf(obj);

return Object.assign({},Object.create(proto),obj);

}

83.實作一個秒針繞一點轉動的效果

1

2

3

4

5

6

7

8

9

10

11

12

animation: move 60s infinite steps(60);

/設定旋轉的中心點為中間底部/

transform-origin: center bottom;

/旋轉從0度到360度/

@keyframes move {

from {

transform: rotate(0deg);

}

to {

transform: rotate(360deg);

}

}

84.移動端相容問題

IOS移動端click事件300ms的延遲響應

一些情況下對非可點選元素如(label,span)監聽click事件,ios下不會觸發,css增加cursor:pointer就搞定了

85.bootstrap的栅格系統如何實作的

box-sizing: border-box;

container row column設定百分比

85.js基本類型及判斷方法

null, undefined,bool,number,string,object,symbol(es6 獨一無二)

1.typeof()出來的沒有null 對象,數組和null typeof(x) = “object”

2.instanceof() 對象的原型是否在對象的原型鍊上

如下:判斷Person的原型是否在p的原型鍊上

1

2

3

function Person(){};

var p =new Person();

console.log(p instanceof Person);//true

3.Object.prototype.toString.call()

每種對象對toString都進行了改寫,隻有Object.prototype.toString.call(obj)可以進行類型判斷

1

2

3

4

var a=new Number(12);

var toString=Object.prototype.toString;

console.log(toString.call(a));//’[object Number]’’

console.log(a.toString());//‘12’

86 JavaScript為什麼是單線程?eventloop

JavaScript的單線程,與它的用途有關。作為浏覽器腳本語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它隻能是單線程,否則會帶來很複雜的同步問題。

比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加内容,另一個線程删除了這個節點,這時浏覽器應該以哪個線程為準?

異步執行:

(1)所有同步任務都在主線程上執行,形成一個執行棧(execution context stack)。

(2)主線程之外,還存在一個"任務隊列"(task queue)。隻要異步任務有了運作結果,就在"任務隊列"之中放置一個事件。

(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務隊列",看看裡面有哪些事件。那些對應的異步任務,于是結束等待狀态,進入執行棧,開始執行。

(4)主線程不斷重複上面的第三步。

主線程從”任務隊列”中讀取事件,這個過程是循環不斷的,是以整個的這種運作機制又稱為Event Loop(事件循環)。

node裡的process.nextTick指定的回調函數是在本次”事件循環”觸發,而setImmediate指定的是在下次”事件循環”觸發,是以很顯然,前者總是比後者發生得早,而且執行效率也高。

87 http http2 https

http(超文本傳輸協定)是一種常用于應用層的協定,它是基于文本傳輸内容。

https可以稱為http安全版,主要是http下增加了SSL(安全套接層)或者TSL(傳輸層安全),在SSL或TSL在傳輸層對資料進行了加密處理。

http/2(超文本傳輸協定第二版),他對http進行了一些更新改造

新的二進制格式
多路複用
header壓縮
支援server push
           

87 枚舉

88 meta屬性

1.name 網頁描述

a.keword

b.description

c.viewport

2.http-equiv http相關描述

a.content-type

b.cache-control

c.expires

89 react 相關

react router:

實作URL與UI界面的同步。其中在react-router中,URL對應Location對象,而UI是由react components來決定的,這樣就轉變成location與components之間的同步問題。

react事件:

React并不是将click事件綁在該div的真實DOM上,而是在document處監聽所有支援的事件,當事件發生并冒泡至document處時,React将事件内容封裝并交由真正的處理函數運作。

90 js css加載順序

js全阻塞,css半阻塞

JS 會阻塞後續 DOM 解析以及其它資源(如 CSS,JS 或圖檔資源)的加載。
CSS 不會阻塞後續 DOM 結構的解析,不會阻塞其它資源(如圖檔)的加載,但是會阻塞 JS 檔案的加載。
現代浏覽器很聰明,會進行 prefetch 優化,浏覽器在獲得 html 文檔之後會對頁面上引用的資源進行提前下載下傳。
           

js為什麼阻塞?

JS 運作在浏覽器中,是單線程的,每個 window 一個 JS 線程,是以當然會阻塞後續 DOM 樹的解析咯。
JS 有可能會修改 DOM 結構,給 DOM 添加樣式等等,是以這就意味着在目前 JS 加載執行完成前,後續資源的加載可能是沒有意義的
           

css為什麼阻塞js?

JS 代碼在執行前,浏覽器必須保證在 JS 之前的所有 CSS 樣式都解析完成,不然不就亂套了,前面的 CSS 樣式可能會覆寫 JS 檔案中定義的元素樣式,這是 CSS 阻塞後續 JS 執行的根本原因。

defer,async?

JS 會阻塞後續 DOM 解析以及其它資源(如 CSS,JS 或圖檔資源)的加載,這是在沒有考慮到 defer, async 的情況下。

由于現代浏覽器都存在 prefetch,是以 defer, async 可能并沒有太多的用途,可以作為了解擴充知識,僅僅将腳本檔案放到 body 底部就可以起到很不錯的優化效果。
defer 和 async 都是異步加載腳本檔案,defer異步加載,最後執行。
慎用 async,因為它完全不考慮依賴關系,隻要下載下傳完後就加載,不考慮此時頁面樣式先後的加載順序,不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合适的,最典型的例子:Google Analytics。
耗時較長的腳本代碼可以使用 defer 來推遲執行。
           
  1. 三次握手四次揮手

第一次握手:用戶端請求與服務端建立連接配接。第二次:服務端傳回确認資訊。第三次:用戶端收到。

客戶:喂?你在嗎?我想跟你聊會兒天兒!(發送SYN請求同步封包)

服務:好的,我聽着呢(發送SYN請求同步封包,意思是說,咱倆同步着呢),你說吧!(發送ACK确認封包,即可以說了)

客戶:好的!(發送ACK确認封包,開始吐槽XXXX)

第一次揮手:用戶端傳完了,想要斷開連接配接。第二次:服務端收到,半關閉狀态。第三次:服務端沒資訊發了,發送結束封包。第四次:用戶端确認,關閉。

然後客戶有事兒要挂電話了,又有了下面一段對話,即四次揮手:

客戶:我有事兒要挂電話了!(發送Fin結束封包,1次揮手)

服務:好吧(發送ACK确認封包,2次揮手),對了,還有個事兒要跟你說!

服務:好了,就這些了,挂了吧!(發送Fin結束封包,3次揮手)

客戶:行,挂了吧!(發送ACK确認封包,4次揮手)

服務挂斷電話…

2MSL後…

客戶:喂,你還在嗎?

啪!(這才斷開連接配接)

為什麼四次揮手?

當被動方收到主動方的FIN封包通知時,它僅僅表示主動方沒有資料再發送給被動方了。

但未必被動方所有的資料都完整的發送給了主動方,是以被動方不會馬上關閉SOCKET,它可能還需要發送一些資料給主動方後,