前端面試題總結 (轉載)

1:爲什麼選擇前端這個方向和對前端的理解javascript

爲何:php

第一的話就是對前端很感興趣,以前也接觸過其餘的語言,可是直到接觸到前端才發現真的有興趣作下去,興趣是一我的最好的老師,css

第二的話前端頗有前途,像如今nodejs,rn,微信小程序這類工具和框架可讓前端進行後端和移動開發,因此我以爲前端的前途會更多一點。html

理解:前端

首先前端工程師最核心的技能仍是:Html、CSS、JS。前端負責的是用戶能夠看到的部分,因此也是最接近用戶的工程師。同時在產品研發流程中前端要同時與產品、設計、後端等不少人合做。vue

2:Vue雙向數據綁定的實現html5

vue.js 則是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的settergetter,在數據變更時發佈消息給訂閱者(文本節點則是做爲訂閱者),在收到消息後執行相應的更新操做。java

compile主要作的事情是解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖node

MVVM做爲數據綁定的入口,整合Observer、Compile和Watcher三者,經過Observer來監聽本身的model數據變化,經過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通訊橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變動的雙向綁定效果。react

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(強緩存)+過時時間   ExpiresHTTP1.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 (!$.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%;
     #ccc;
    float: left;
}
#right{
    height: 100%;
    margin-left: 300px;
    #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%;
     #ccc;
    float: left;
}
#right{
    height: 100%;
    overflow:hidden;
    #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-growflex-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  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標籤沒有同源限制

經過動態<script>元素使用,使用時爲src指定一個跨域url。回調函數處理JSON數據  兼容性好 不支持post

簡述原理與過程:首先在客戶端註冊一個callback, 而後把callback的名字傳給服務器。此時,服務器先生成一個function , function 名字就是傳遞上來的參數。最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時數據做爲參數,傳入到了客戶端預先定義好的 callback 函數裏

1
2
3
4
5
6
7
8
9
10
11
   <script> 
   var  url =  "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction" ;  
   var  script = document.createElement( 'script' );  
   script.setAttribute( 'src' , url);   //load javascript   
   document.getElementsByTagName( 'head' )[0].appendChild(script);  
   
   //回調函數 
    function  callbackfunction(data){ 
var  html=JSON.stringify(data.RESULTSET); 
alert(html); 
     

cors:經過設置Access-Control-Allow-Origin來容許跨域 cors可用ajax發請求獲取數據 可是兼容性沒有jsonp好 

43:多頁面通訊有哪些方案,各有什麼不一樣

localstorge在一個標籤頁裏被添加、修改或刪除時,都會觸發一個storage事件,經過在另外一個標籤頁裏監聽storage事件,便可獲得localstorge存儲的值,實現不一樣標籤頁之間的通訊。

settimeout+cookie

44:用Node實現一個用戶上傳文件的後臺服務應該怎麼作

multer模塊

45: XSS和CSRF攻擊

xss:好比在一個論壇發帖中發佈一段惡意的JavaScript代碼就是腳本注入,若是這個代碼內容有請求外部服務器,那麼就叫作XSS

寫一個腳本將cookie發送到外部服務器這就是xss攻擊可是沒有發生csrf

防範:對輸入內容作格式檢查 輸出的內容進行過濾或者轉譯

CSRF:又稱XSRF,冒充用戶發起請求(在用戶不知情的狀況下),完成一些違背用戶意願的請求 如惡意發帖,刪帖

好比在論壇發了一個刪帖的api連接 用戶點擊連接後把本身文章給刪了 這裏就是csrf攻擊沒有發生xss

防範:驗證碼 token 來源檢測

46:聖盃佈局和雙飛翼佈局

【聖盃佈局】

html代碼中  middle部分首先要放在container的最前部分。而後是left,right

1.將三者都 float:left , 再加上一個position:relative (由於相對定位後面會用到)

2.middle部分 width:100%佔滿

3.此時middle佔滿了,因此要把left拉到最左邊,使用margin-left:-100%

4.這時left拉回來了,但會覆蓋middle內容的左端,要把middle內容拉出來,因此在外圍container加上 padding:0 220px 0 200px

5.middle內容拉回來了,但left也跟着過來了,因此要還原,就對left使用相對定位 left:-200px  同理,right也要相對定位還原 right:-220px

6.到這裏大概就自適應好了。若是想container高度保持一致能夠給left middle right都加上min-height:130px

【雙飛翼佈局】

前幾步都同樣 後邊把外圍padding和相對定位作法換成內層margin

給middle增長一個內層div-- middle-inner, 而後margin:0 220px 0 200px

47:offsetHeight, scrollHeight, clientHeight分別表明什麼

clientHeight:包括內容可見部分的高度,可見的padding;不包括border,水平方向的scrollbarmargin

offsetHeight:包括內容可見部分的高度,border,可見的padding,水平方向的scrollbar(若是存在);不包括margin

scrollHeight:包括內容的高度(可見與不可見),padding(可見與不可見);不包括bordermargin

48:垂直居中

單行行內元素 1.能夠設置padding-top,padding-bottom 2.將height和line-height設爲相等

多行行內元素 1.能夠將元素轉爲table樣式,再設置vertical-align:middle; 2.使用flex佈局

塊級元素

已知高度絕對定位負邊距

未知高度transform: translateY(-50%);

flex佈局 
display: flex;
justify-content: center;
align-items: center;

49:transition的屬性值和應用

屬性的名稱 過渡時間 時間曲線 延遲

50:rem和em的區別

em相對於父元素,rem相對於根元素

51:嚴格模式的特性

嚴格模式對Javascript的語法和行爲,都作了一些改變。

全局變量必須顯式聲明。

對象不能有重名的屬性

函數必須聲明在頂層

  • 消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲;
  • 消除代碼運行的一些不安全之處,保證代碼運行的安全;
  • 提升編譯器效率,增長運行速度;
  • 爲將來新版本的Javascript作好鋪墊。

52:js的原型鏈,如何實現繼承?

原型鏈實際上就是js中數據繼承的繼承鏈。
在訪問一個實例的屬性的時候,如今實例自己中找,若是沒找到就去它的原型中找,還沒找到就再往上找,直到找到。這就是原型鏈。

1
2
3
4
5
6
7
8
function  foo(){}
foo.prototype.z = 3;
var  obj =  new  foo();
obj.x=1;
obj.y=2;
obj.x  //1
obj.y  //2
obj.z  //3<br><br>obj.__proto__===foo.prototype   true<br>foo.prototype.constructor === foo<br>

53:圖片預加載和懶加載

預加載:

1
2
3
4
5
6
7
8
9
10
11
function  loadImage(url, callback) {
     var  img =  new  Image();
     img.src = url;
     if  (img.complete) {  // 若是圖片已經存在於瀏覽器緩存,直接調用回調函數 防止IE6不執行onload BUG
         callback.call(img);
         return ;
     }
     img.onload =  function  () {
         callback.call(img); //將回調函數的this替換爲Image對象
     };
};

懶加載:

當網頁滾動的事件被觸發 -> 執行加載圖片操做 -> 判斷圖片是否在可視區域內 -> 在,則動態將data-src的值賦予該圖片。

 

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
27
28
29
30
31
32
var  aImages = document.getElementById( "SB" ).getElementsByTagName( 'img' );  //獲取id爲SB的文檔內全部的圖片
loadImg(aImages);
window.onscroll =  function () {  //滾動條滾動觸發
loadImg(aImages);
};
//getBoundingClientRect 是圖片懶加載的核心
function  loadImg(arr) {
for ( var  i = 0, len = arr.length; i < len; i++) {
  if (arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) {
  arr[i].isLoad =  true //圖片顯示標誌位
  //arr[i].style.cssText = "opacity: 0;";
  ( function (i) {
   setTimeout( function () {
   if (arr[i].dataset) {  //兼容不支持data的瀏覽器
    aftLoadImg(arr[i], arr[i].dataset.imgurl);
   else  {
    aftLoadImg(arr[i], arr[i].getAttribute( "data-imgurl" ));
   }
   arr[i].style.cssText =  "transition: 1s; opacity: 1;"  //至關於fadein
   }, 500)
  })(i);
  }
}
}
 
function  aftLoadImg(obj, url) {
var  oImg =  new  Image();
oImg.onload =  function () {
  obj.src = oImg.src;  //下載完成後將該圖片賦給目標obj目標對象
}
oImg.src = url;  //oImg對象先下載該圖像
}

 

54.輸入網址後到頁面展示的過程

經過dns解析獲取ip

tcp連接

客戶端發送http請求

tcp傳輸報文

服務器處理請求返回http報文

客戶端解析渲染頁面 (構建DOM樹 –> 構建渲染樹 –> 佈局渲染樹:計算盒模型位置和大小 –> 繪製渲染樹)

 

55:UMD規範和ES6模塊化,Commonjs的對比

CommonJS是一個更偏向於服務器端的規範。用於NodeJS 是同步的

AMD是依賴前置的

CMD推崇依賴就近,延遲執行。能夠把你的依賴寫進代碼的任意一行

AMD和CMD都是用difine和require,可是CMD標準傾向於在使用過程當中提出依賴,就是無論代碼寫到哪忽然發現須要依賴另外一個模塊,那就在當前代碼用require引入就能夠了,規範會幫你搞定預加載,你隨便寫就能夠了。可是AMD標準讓你必須提早在頭部依賴參數部分寫好(沒有寫好? 倒回去寫好咯)。這就是最明顯的區別。

UMD寫一個文件須要兼容不一樣的加載規範

ES6經過importexport實現模塊的輸入輸出。其中import命令用於輸入其餘模塊提供的功能,export命令用於規定模塊的對外接口。

56:http請求頭

get post delete put head options trace connect

OPTIONS:返回服務器針對特定資源所支持的HTTP請求方法

57:nginx的好處?和node的比較

高併發 響應快

區別不是很大,一個更專業,一個更全面:
1.類似點:
1.1異步非阻塞I/O, 事件驅動;
2.不一樣點:
2.1Nginx 採用C編寫,更性能更高,可是它僅適合於作web服務器,用於反向代理或者負載均衡等服務;Nginx背後的業務層編程思路很仍是同步編程方式,例如PHP.
2.2NodeJs高性能平臺,web服務只是其中一塊,NodeJs在處理業務層用的是JS編寫,採用的是異步編程方式和思惟方式。

58.框架問題

  • 什麼是 MVVM , 和 MVC 是什麼區別, 原理是什麼?

  mvc的界面和邏輯關聯緊密,數據直接從數據庫讀取,必須經過Controller來承上啓下,通訊都是單向的。mvvm的View 和 ViewModel能夠互相通訊,界面數據從viewmodel中獲取。

  • 父子組件怎麼通訊的?
  vue:父組件是經過props屬性給子組件通訊  在子組件裏面emit,在父組件監聽
  react:props傳遞  父給子傳一個回調函數 將數據傳給父親處理
  • 兄弟組件怎麼通訊的?

  vuex 創建一個vue實例 emit觸發事件 on監聽事件

  redux  子A -> 父 -> 子B

  • 生命週期有哪些, 怎麼用?
  beforecreated:el 和 data 並未初始化 
  created:完成了 data 數據的初始化,el沒有
  beforeMount:完成了 el 和 data 初始化 

  mounted :完成掛載  updated;destroyed

  react:初始化階段、運行中階段、銷燬階段

  初始化getDefaultProps()getInitialState()初始化

    componentWillMount() 在組件即將被渲染到頁面

  render() 組件渲染
    componentDidMount() 組件被渲染到頁面上,

  運行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate() 
  銷燬componentWillUnmount()

59:清除浮動

兩種原理:

一、利用clear屬性進行清理

具體的實現原理是經過引入清除區域,這個至關於加了一塊看不見的框把定義clear屬性的元素向下擠
父容器結尾插入空標籤<div style="clear: both;"></div>

利用CSS僞元素:

1
2
3
4
5
6
7
.clearfix:after {
   content:  "." ;
   height: 0;
   visibility: hidden;
   display: block;
   clear: both;
}

經過將這個類添加到父容器當中,會在父容器的末尾增長了一個高度爲0、具備清除屬性的、不可見的塊級元素。

二、將父容器造成BFC

BFC能清理浮動主要運用的是它的佈局規則:

  1. 內部的Box會在垂直方向,一個接一個地放置。
  2. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  3. 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。
  4. BFC的區域不會與float box重疊。
  5. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
  6. 計算BFC的高度時,浮動元素也參與計算

浮動清理利用的主要是第六條規則,只要將父容器觸發爲BFC,就能夠實現包含的效果。

那麼觸發BFC有哪幾種方法?

  1. 根元素
  2. float屬性不爲none
  3. position爲absolute或fixed
  4. display爲inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不爲visible

60.前端性能優化

1.減小http請求 使用sprite圖、合併js和css文件

2.使用cdn 將用戶安排在近的服務器上

3.使用緩存 緩存ajax 使用外部的css和js以便緩存 使用expire cach-control etag

4.壓縮資源 使用gzip壓縮js和css文件

5.代碼層面 避免使用樣式表達式、通配符選擇器、樣式放在頂部、腳本放在底部

61.事件模型和事件代理

事件三個階段:事件捕獲,目標,事件冒泡(低版本ie不支持捕獲階段)

w3c綁定事件target.addEventListener(event,handler,false)

解綁target.removeEventListener(eventType, handler, false)

ie綁定 target.attachEvent(on+event, handler)

解綁target.detachEvent("on"+eventType, handler)

事件代理優勢:

  • 能夠大量節省內存佔用,減小事件註冊,好比在table上代理全部td的click事件就很是棒

  • 能夠實現當新增子對象時無需再次對其綁定事件,對於動態內容部分尤其合適

bind和trigger實現:

建立一個類或是匿名函數,在bind和trigger函數外層做用域建立一個字典對象,用於存儲註冊的事件及響應函數列表,bind時,若是字典沒有則建立一個,key是事件名稱,value是數組,裏面放着當前註冊的響應函數,若是字段中有,那麼就直接push到數組便可。trigger時調出來依次觸發事件響應函數便可。

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
function  Emitter() {
     this ._listener = []; //_listener[自定義的事件名] = [所用執行的匿名函數1, 所用執行的匿名函數2]
}
  
//註冊事件
Emitter.prototype.bind =  function (eventName, callback) {
     var  listener =  this ._listener[eventName] || []; //this._listener[eventName]沒有值則將listener定義爲[](數組)。
     listener.push(callback);
     this ._listener[eventName] = listener;
}
  
  //觸發事件
Emitter.prototype.trigger =  function (eventName) {
     var  args = Array.prototype.slice.apply(arguments).slice(1); //atgs爲得到除了eventName後面的參數(註冊事件的參數)
     var  listener =  this ._listener[eventName];
  
     if (!Array.isArray(listener))  return ; //自定義事件名不存在
     listener.forEach( function (callback) {
         try  {
             callback.apply( this , args);
         } catch (e) {
             console.error(e);
         }
     })
}

  

62.將url的查詢參數解析成字典對象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function  getQueryObject(url) {
     url = url ==  null  ? window.location.href : url;
     var  search = url.substring(url.lastIndexOf( "?" ) + 1);
     var  obj = {};
     var  reg = /([^?&=]+)=([^?&=]*)/g;
     search.replace(reg,  function  (rs, $1, $2) {
         var  name = decodeURIComponent($1);
         var  val = decodeURIComponent($2);              
         val = String(val);
         obj[name] = val;
         return  rs;
     });
     return  obj;
}
  
getQueryObject( "http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**" )
Object {name:  "1" , dd:  "ddd**" }

  

63.position的值, relative和absolute分別是相對於誰進行定位的?
<1>、relative:相對定位,相對於本身自己在正常文檔流中的位置進行定位。
<2>、absolute:生成絕對定位,相對於最近一級定位不爲static的父元素進行定位。
<3>、fixed: 生成絕對定位,相對於瀏覽器窗口或者frame進行定位。
<4>、static:默認值,沒有定位,元素出如今正常的文檔流中。
<5>、sticky:生成粘性定位的元素,容器的位置根據正常文檔流計算得出。

64.position:absolute和float屬性的異同?
共同點:對內聯元素設置float和absolute屬性,可讓元素脫離文檔流,而且能夠設置其寬高。
不一樣點:float仍可佔據位置,不會覆蓋在另外一個BFC區域上,浮動的框能夠向左或向右移動,直到它的外邊緣碰到包含框或另外一個浮動框的邊框爲止。absolute會覆蓋文檔流中的其餘元素。

65.CSS 選擇符有哪些?哪些屬性能夠繼承?優先級算法如何計算? CSS3新增僞類有那些?

選擇符
<1>、id選擇器(#myId);
<2>、類選擇器(.myClassName);
<3>、標籤選擇器(div,p,h1);
<4>、相鄰選擇器(h1 + p);
<5>、子選擇器(ul > li);
<6>、後代選擇器(li a);
<7>、通配符選擇器(*);
<8>、屬性選擇器(button[disabled="true"]);
<9>、僞類選擇器(a:hover,li:nth-child);表示一種狀態
<10>、僞元素選擇器(li:before、:after,:first-letter,:first-line,:selecton);表示文檔某個部分的表現

優先級
!important > 行內樣式(比重1000) > id(比重100) > class/屬性(比重10) > tag / 僞類(比重1);

僞類和僞元素區別
1>、僞類:a:hover,li:nth-child;
2>、僞元素:li:before、:after,:first-letter,:first-line,:selecton;

65.兩個數組合併成一個數組排序返回

先依次比較兩個數組,按照小的就傳入新的數組。當此次比較完以後可能有一個數組的長度很長,留下一些數組,而後在新數組的末尾插入便可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
functiongetRes(arr1, arr2){
    var  len1 = arr1.length,
        len2 = arr2.length,
        i = 0,
        j = 0,
        k = 0,
        res =  new  Array(len1+len2);
  
        while (i < len1 && j <len2){
res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++];
}
While(i < len1)   res[k++]= arr1[i++];
While(j < len2)   res[k++]= arr2[j++];
Return res;
}

66.zepto和jquery區別

zepto比jquery體積小不少,移動端的兼容性不須要要考慮不少,jquery中的不少功能都沒有。

width()和height()不同  解決用.css('width')

67.css3動畫和jquery動畫的差異

1.css3中的過渡和animation動畫都是基於css實現機制的,屬於css範疇以內,並無涉及到任何語言操做。效率略高與jQuery中的animate()函數,但兼容性不好。

2.jQuery中的animate()函數能夠簡單的理解爲css樣式的「逐幀動畫」,是css樣式不一樣狀態的快速切換的結果。效率略低於css3動畫執行效率,可是兼容性好。‍

68.如何解決ajax沒法後退的問題

HTML5裏引入了新的API,即:history.pushState, history.replaceState

能夠經過pushState和replaceState接口操做瀏覽器歷史,而且改變當前頁面的URL。

onpopstate監聽後退

69.實現一個once函數

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function  test () {console.log( 'test' )}
 
var  once =  function  (fn) {
   var  isFirst =  true ;
   return  function  () {
     if  (isFirst) {
       isFirst = !isFirst;
       fn();
     }
   };
};
 
var  b = once(test);
b();  // 'test'
b();  // nothing

 

70.分域名請求圖片的緣由和好處

瀏覽器的併發請求數目限制是針對同一域名的,超過限制數目的請求會被阻塞

瀏覽器併發請求有個數限制,分域名能夠同時併發請求大量圖片

 

71.頁面的加載順序

html順序加載,其中js會阻塞後續dom和資源的加載,css不會阻塞dom和資源的加載可是會阻塞js的加載。

瀏覽器會使用prefetch對引用的資源提早下載

1.沒有 defer 或 async,瀏覽器會當即加載並執行指定的腳本

2.有 async,加載和渲染後續文檔元素的過程將和 script.js 的加載與執行並行進行(下載異步,執行同步,加載完就執行)。

3.有 defer,加載後續文檔元素的過程將和 script.js 的加載並行進行(異步),可是 script.js 的執行要在全部元素解析完成以後,DOMContentLoaded 事件觸發以前完成。

72.生成10個20-50之間的隨機數,存在數組中,常見排序方法,數組亂序方法

1
2
3
4
5
6
var  arr = [];
for ( var  i = 0;i<10;i++){
     var  num = Math.random()*30 + 20;
     num = parseInt(num, 10);
     arr.push(num);
}

 

1
2
3
arr.sort( function (a,b){
     return  0.5 - Math.random();
})

73.計算機網絡的分層概述

tcp/ip模型:從下往上分別是鏈路層,網絡層,傳輸層,應用層

osi模型:從下往上分別是物理層,鏈路層,網絡層,傳輸層,會話層,表示層,應用層。

73.jscss緩存問題

瀏覽器緩存的意義在於提升了執行效率,可是也隨之而來帶來了一些問題,致使修改了js、css,客戶端不能更新

都加上了一個時間戳做爲版本號

<script type=」text/javascript」 src=」{JS文件鏈接地址}?version=XXXXXXXX」></script>

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  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(p) {
     var  c = {};
     for  ( var  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  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 網頁描述

<meta name="參數" content="描述內容">

a.keword

b.description

c.viewport

2.http-equiv http相關描述

<meta http-equiv="參數" content="描述內容">

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半阻塞

  1. JS 會阻塞後續 DOM 解析以及其它資源(如 CSS,JS 或圖片資源)的加載。
  2. CSS 不會阻塞後續 DOM 結構的解析,不會阻塞其它資源(如圖片)的加載,可是會阻塞 JS 文件的加載。
  3. 現代瀏覽器很聰明,會進行 prefetch 優化,瀏覽器在得到 html 文檔以後會對頁面上引用的資源進行提早下載。

js爲何阻塞?

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

css爲何阻塞js?

JS 代碼在執行前,瀏覽器必須保證在 JS 以前的全部 CSS 樣式都解析完成,否則不就亂套了,前面的 CSS 樣式可能會覆蓋 JS 文件中定義的元素樣式,這是 CSS 阻塞後續 JS 執行的根本緣由。

defer,async?

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

  1. 因爲現代瀏覽器都存在 prefetch,因此 defer, async 可能並無太多的用途,能夠做爲了解擴展知識,僅僅將腳本文件放到 body 底部就能夠起到很不錯的優化效果。
  2. defer 和 async 都是異步加載腳本文件,defer異步加載,最後執行。
  3. 慎用 async,由於它徹底不考慮依賴關係,只要下載完後就加載,不考慮此時頁面樣式前後的加載順序,不過它對於那些能夠不依賴任何腳本或不被任何腳本依賴的腳原本說倒是很是合適的,最典型的例子:Google Analytics。
  4. 耗時較長的腳本代碼可使用 defer 來推遲執行。

 91. 三次握手四次揮手

第一次握手:客戶端請求與服務端創建鏈接。第二次:服務端返回確認信息。第三次:客戶端收到。

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

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

客戶:好的!(發送ACK確認報文,開始吐槽XXXX)

 

第一次揮手:客戶端傳完了,想要斷開鏈接。第二次:服務端收到,半關閉狀態。第三次:服務端沒信息發了,發送結束報文。第四次:客戶端確認,關閉。

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

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

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

......

服務:好了,就這些了,掛了吧!(發送Fin結束報文,3次揮手)

客戶:行,掛了吧!(發送ACK確認報文,4次揮手)

服務掛斷電話.....

2MSL後......

客戶:喂,你還在嗎?

啪!(這才斷開鏈接)

 爲何四次揮手?

當被動方收到主動方的FIN報文通知時,它僅僅表示主動方沒有數據再發送給被動方了。

但未必被動方全部的數據都完整的發送給了主動方,因此被動方不會立刻關閉SOCKET,它可能還須要發送一些數據給主動方後,

相關文章
相關標籤/搜索