WEB前端面試題整理

 

HTML:javascript

 

1. 說下行內元素和塊級元素的區別?行內塊元素的兼容性使用?(IE8 如下)
   (1)行內元素:會在水平方向排列,不能包含塊級元素,設置width無效,height無效(能夠設置line-height),margin上下無效,padding上下無效。
       塊級元素:各佔據一行,垂直方向排列。重新行開始結束接着一個斷行。
   (2)兼容性:display:inline-block;*display:inline;*zoom:1; php

2.HTML5 爲何只須要寫 <!DOCTYPE HTML>?
   HTML5不基於 SGML,所以不須要對DTD進行引用,可是須要doctype來規範瀏覽器的行爲(讓瀏覽器按照它們應該的方式來運行)。
   而HTML4.01基於SGML,因此須要對DTD進行引用,才能告知瀏覽器文檔所使用的文檔類型。 css

3.你知道多少種Doctype文檔類型? 

   該標籤可聲明三種 DTD 類型,分別表示嚴格版本、過渡版本以及基於框架的 HTML 文檔。
 HTML 4.01規定了三種文檔類型:Strict、Transitional 以及 Frameset。
   XHTML 1.0規定了三種 XML 文檔類型:Strict、Transitional 以及 Frameset。
 Standards(標準)模式(也就是嚴格呈現模式)用於呈現遵循最新標準的網頁,而 Quirks

 (包容)模式(也就是鬆散呈現模式或者兼容模式)用於呈現爲傳統瀏覽器而設計的網頁。 html

4.Doctype做用?標準模式與兼容模式各有什麼區別?
   (1)<!DOCTYPE>告知瀏覽器的解析器用什麼文檔標準解析這個文檔。DOCTYPE不存在或格式不正確會致使文檔以兼容模式呈現。
    (2)標準模式的排版和JS運做模式都是以該瀏覽器支持的最高標準運行。在兼容模式中,頁面以寬鬆的向後兼容的方式顯示,模擬老式瀏覽器的行爲以防止站點沒法工做。 前端

5.嚴格模式和混雜模式的區分,以及如何觸發這2種模式? vue

嚴格模式就是瀏覽器根據web標準去解析頁面,是一種要求嚴格的DTD,不容許使用任何表現層的語法,如 html5

混雜模式是一種向後兼容的解析方法。 java

觸發標準模式或者說嚴格模式很簡單,就是Html前申明正確的DTD,出發混雜模式能夠在html文檔開始不聲明DTD,或者在DOCTYPE前加入XML聲明(DOCTYPE不存在或格式不正確會致使文檔以混雜模式呈現。) node

6.說說嚴格模式的限制 

嚴格模式主要有如下限制: mysql

     變量必須聲明後再使用
 函數的參數不能有同名屬性,不然報錯
 不能使用with語句
 不能對只讀屬性賦值,不然報錯
 不能使用前綴0表示八進制數,不然報錯
 不能刪除不可刪除的屬性,不然報錯
 不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
 eval不會在它的外層做用域引入變量
 eval和arguments不能被從新賦值
 arguments不會自動反映函數參數的變化
 不能使用arguments.callee
 不能使用arguments.caller
 禁止this指向全局對象
 不能使用fn.caller和fn.arguments獲取函數調用的堆棧
 增長了保留字(好比protected、static和interface)

7.設立」嚴格模式」的目的,主要有如下幾個: 

消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲; 

消除代碼運行的一些不安全之處,保證代碼運行的安全; 

提升編譯器效率,增長運行速度; 

爲將來新版本的Javascript作好鋪墊。 

注:通過測試IE6,7,8,9均不支持嚴格模式。 

8.頁面導入樣式時,使用link和@import有什麼區別?
  (1)link屬於XHTML標籤,除了加載CSS外,還能用於定義RSS, 定義rel鏈接屬性等做用;而@import是CSS提供的,只能用於加載CSS;
  (2)頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載;
  (3)import是CSS2.1 提出的,只在IE5以上才能被識別,而link是XHTML標籤,無兼容問題; 

9.html5有哪些新特性?如何處理HTML5新標籤的瀏覽器兼容問題?如何區分 HTML 和 HTML5?
(Q1) 
     HTML5 如今已經不是 SGML 的子集,主要是關於圖像,位置,存儲,多任務等功能的增長。
     (1)繪畫 canvas;
     (2)用於媒介回放的 video 和 audio 元素;
     (3)本地離線存儲 localStorage 長期存儲數據,瀏覽器關閉後數據不丟失;
     (4)sessionStorage 的數據在瀏覽器關閉後自動刪除;
     (5)語意化更好的內容元素,好比 article、footer、header、nav、section;
     (6)表單控件,calendar、date、time、email、url、search;
     (7)新的技術webworker, websocket, Geolocation;
 (Q2)
     IE8/IE7/IE6支持經過document.createElement方法產生的標籤,
     能夠利用這一特性讓這些瀏覽器支持HTML5新標籤,
     瀏覽器支持新標籤後,還須要添加標籤默認的樣式。
     固然也能夠直接使用成熟的框架、好比html5shim;
<!--[if lt IE 9]>
   <script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script>
<![endif]--> 

10.簡述一下你對HTML語義化的理解?
   用正確的標籤作正確的事情。
   (1)html語義化讓頁面的內容結構化,結構更清晰,便於對瀏覽器、搜索引擎解析;
   (2) 即便在沒有樣式CSS狀況下也以一種文檔格式顯示,而且是容易閱讀的;
   (3) 搜索引擎的爬蟲也依賴於HTML標記來肯定上下文和各個關鍵字的權重,利於SEO;
   (4) 使閱讀源代碼的人對網站更容易將網站分塊,便於閱讀維護理解。 

11.Html和xhtml有什麼區別? 

html是一種基本的web網頁設計語言,xhtml是一個基於XML的置標語言。 

最主要的不一樣: 

XHTML元素必須正確的被嵌套,元素必須關閉,標籤必須小寫,必須有根元素。 

12.行內元素有哪些?塊級元素有哪些?CSS盒模型 

行內元素: br span input a 

塊級元素IV P H1 H2 FORM ul 

CSS盒模型內容:padding border margin 

13.iframe有那些缺點?
iframe會阻塞主頁面的Onload事件;
搜索引擎的檢索程序沒法解讀這種頁面,不利於SEO;
iframe和主頁面共享鏈接池,而瀏覽器對相同域的鏈接有限制,因此會影響頁面的並行加載。
使用iframe以前須要考慮這兩個缺點。若是須要使用iframe,最好是經過javascript動態給iframe添加src屬性值,這樣能夠繞開以上兩個問題。 

14.<strong><em><b><i>標籤 

<strong> 標籤和 <em> 標籤同樣,用於強調文本,但它強調的程度更強一些。 

em 是 斜體強調標籤,更強烈強調,表示內容的強調點。至關於html元素中的 <i>...</i>; 

< b > < i >是視覺要素,分別表示無心義的加粗,無心義的斜體。

em 和 strong 是表達要素(phrase elements)。   

 

CSS:

行內元素有哪些?塊級元素有哪些? 空(void)元素有那些?

行內元素:a、b、span、img、input、strong、select、label、em、button、textarea
塊級元素:div、ul、li、dl、dt、dd、p、h1-h六、blockquote
空元素:即系沒有內容的HTML元素,例如:br、meta、hr、link、input、img

 

1.清除浮動有哪些方式?比較好的方式是哪種?
  (Q1)
     (1)父級div定義height。
     (2)結尾處加空div標籤clear:both。
     (3)父級div定義僞類:after和zoom。
     (4)父級div定義overflow:hidden。
     (5)父級div定義overflow:auto。
     (6)父級div也浮動,須要定義寬度。
     (7)父級div定義display:table。
     (8)結尾處加br標籤clear:both。

(9)使用空標籤清除浮動。
       這種方法是在全部浮動標籤後面添加一個空標籤 定義css clear:both. 弊端就是增長了無心義標籤。
(10)使用overflow。

           給包含浮動元素的父標籤添加css屬性 overflow:auto; zoom:1; zoom:1用於兼容IE6。
   (Q2)比較好的是第3種方式,好多網站都這麼用。

2.box-sizing經常使用的屬性有哪些?分別有什麼做用?
    (Q1)box-sizing: content-box|border-box|inherit;
    (Q2)content-box:寬度和高度分別應用到元素的內容框。在寬度和高度以外繪製元素的內邊距和邊框(元素  默認效果)。
        border-box:元素指定的任何內邊距和邊框都將在已設定的寬度和高度內進行繪製。經過從已設定的寬  度和高度分別減去邊框和內邊距才能獲得內容的寬度和高度。

3.介紹一下box-sizing屬性?

box-sizing屬性主要用來控制元素的盒模型的解析模式。默認值是content-box

content-box:讓元素維持W3C的標準盒模型。元素的寬度/高度由border + padding + content的寬度/高度決定,設置width/height屬性指的是content部分的寬/高

border-box:讓元素維持IE傳統盒模型(IE6如下版本和IE6~7的怪異模式)。設置width/height屬性指的是border + padding + content

標準瀏覽器下,按照W3C規範對盒模型解析,一旦修改了元素的邊框或內距,就會影響元素的盒子尺寸,就不得不從新計算元素的盒子尺寸,從而影響整個頁面的佈局。

4.CSS3中新增了一種盒模型計算方式:box-sizing。盒模型默認的值是content-box, 新增的值是padding-boxborder-box,幾種盒模型計算元素寬高的區別以下:

content-box(默認)

佈局所佔寬度Width:

Width = width + padding-left + padding-right + border-left + border-right

佈局所佔高度Height:

Height = height + padding-top + padding-bottom + border-top + border-bottom

 

padding-box

佈局所佔寬度Width:

Width = width(包含padding-left + padding-right) + border-top + border-bottom

佈局所佔高度Height:

Height = height(包含padding-top + padding-bottom) + border-top + border-bottom

 

border-box

佈局所佔寬度Width:

Width = width(包含padding-left + padding-right + border-left + border-right)

佈局所佔高度Height:

Height = height(包含padding-top + padding-bottom + border-top + border-bottom)

5.介紹一下標準的CSS的盒子模型?低版本IE的盒子模型有什麼不一樣的?
(1)有兩種, IE 盒子模型、W3C 盒子模型。
(2)盒模型: 內容(content)、填充(padding)、邊界(margin)、 邊框(border)。
(3)區  別: IE的content部分把 border 和 padding計算了進去。

什麼是盒子模型?

在網頁中,一個元素佔有空間的大小由幾個部分構成,其中包括元素的內容(content),元素的內邊距(padding),元素的邊框(border),元素的外邊距(margin)四個部分。這四個部分佔有的空間中,有的部分能夠顯示相應的內容,而有的部分只用來分隔相鄰的區域或區域。4個部分一塊兒構成了css中元素的盒模型。

 

6.IE 8如下版本的瀏覽器中的盒模型有什麼不一樣?
IE8如下瀏覽器的盒模型中定義的元素的寬高不包括內邊距和邊框

7.css引入的方式有哪些?link和@import的區別?

引入方式3種:行內添加定義style屬性值,頁面頭部內內嵌調用和外鏈調用,

區別:

1.link是xhtml標籤,除了加載css外,還能夠定義RSS等其餘事務,@import只能加載CSS

2.link引用CSS時候,頁面載入的時候同時加載,@import須要頁面網頁徹底載入後加載

3.link是XHTML標籤,沒有兼容問題,@import是在CSS2.1提出的,低版本的瀏覽器不支持。

4.link支持使用javascript控制DOM去改變樣式,可是@import不支持。

8.CSS選擇符有哪些? 哪些屬性能夠繼承?優先級算法如何計算?內聯和Important哪一個優先級高?

1.id選擇器( # myid)

    2.類選擇器(.myclassname)

    3.標籤選擇器(div, h1, p)

    4.相鄰選擇器(h1 + p)

    5.子選擇器(ul > li)

    6.後代選擇器(li a)

    7.通配符選擇器( * )

    8.屬性選擇器(a[rel = "external"])

9.僞類選擇器(a: hover, li:nth-child)

important 比 內聯優先級高,但內聯比 id 要高

9.img標籤上的title和alt屬性區別是什麼?

alt是當圖片不能正常顯示的時候,用文字代替

title該屬性提供信息

10.display:nonevisibility:hidden的區別?

     diplay:none  隱藏對應的元素,在文檔佈局中再也不給它分配空間,它各邊的元素會合攏,就當他歷來不存在。

     visibility:hidden  隱藏對應的元素,可是在文檔佈局中仍保留原來的空間。

11.position的值? relative和absolute分別是相對於誰進行定位的?

(1)absolute :生成絕對定位的元素, 相對於最近一級的 定位不是 static 的父元素來進行定位。

    (2)fixed (老IE不支持)生成絕對定位的元素,一般相對於瀏覽器窗口或 frame 進行定位。

(3)relative 生成相對定位的元素,相對於其在普通流中的位置進行定位。

(4)static 默認值。沒有定位,元素出如今正常的流中

(5)sticky 生成粘性定位的元素,容器的位置根據正常文檔流計算得出

12.position:absolutefloat屬性的異同

共同點:對內聯元素設置floatabsolute屬性,可讓元素脫離文檔流,而且能夠設置其寬高。

不一樣點:float仍會佔據位置,absolute會覆蓋文檔流中的其餘元素。

13.如何在頁面上實現一個圓形的可點擊區域?
(1)map+area或者svg
(2)border-radius
(3)純js實現 須要求一個點在不在圓上簡單算法、獲取鼠標座標等等

14.CSS3新增僞類舉例:

    p:first-of-type 選擇屬於其父元素的首個 <p> 元素的每一個 <p> 元素。

    p:last-of-type  選擇屬於其父元素的最後 <p> 元素的每一個 <p> 元素。

    p:only-of-type  選擇屬於其父元素惟一的 <p> 元素的每一個 <p> 元素。

    p:only-child    選擇屬於其父元素的惟一子元素的每一個 <p> 元素。

    p:nth-child(2)  選擇屬於其父元素的第二個子元素的每一個 <p> 元素。

    :enabled  :disabled 控制表單控件的禁用狀態。

:checked        單選框或複選框被選中。

15.css3有哪些新特性?

CSS3實現圓角(border-radius),陰影(box-shadow),
對文字加特效(text-shadow、),線性漸變(gradient),旋轉(transform)
transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋轉,縮放,定位,傾斜
增長了更多的CSS選擇器  多背景 rgba
在CSS3中惟一引入的僞元素是::selection.
媒體查詢,多欄佈局
border-image

16.常見兼容性問題?

(1)png24位的圖片在iE6瀏覽器上出現背景,解決方案是作成PNG8.也能夠引用一段腳本處理.
(2)瀏覽器默認的margin和padding不一樣。解決方案是加一個全局的*{margin:0;padding:0;}來統一。
(3)IE6雙邊距bug:塊屬性標籤float後,又有橫行的margin狀況下,在ie6顯示margin比設置的大。
(4)浮動ie產生的雙倍距離(IE6雙邊距問題:在IE6下,若是對元素設置了浮動,同時又設置了margin-left或margin-right,margin值會加倍。)
(5)#box{ float:left; width:10px; margin:0 0 0 100px;}
這種狀況之下IE會產生20px的距離,解決方案是在float的標籤樣式控制中加入_display:inline;將其轉化爲行內屬性。(_這個符號只有ie6會識別)
    漸進識別的方式,從整體中逐漸排除局部。
        首先,巧妙的使用「\9」這一標記,將IE遊覽器從全部狀況中分離出來。
        接着,再次使用「+」將IE8和IE七、IE6分離開來,這樣IE8已經獨立識別。
  css
      .bb{
       /*全部識別*/
      .background-color:#00deff\9; /*IE6、七、8識別*/
      +/*IE6、7識別*/
      _background-color:#1e0bd1;/*IE6識別*/
      }
    怪異模式問題:漏寫DTD聲明,Firefox仍然會按照標準模式來解析網頁,但在IE中會觸發
    怪異模式。爲避免怪異模式給咱們帶來沒必要要的麻煩,最好養成書寫DTD聲明的好習慣。如今
    能夠使用[html5](http://www.w3.org/TR/html5/single-page.html)推薦的寫法:`<doctype html>`
17.上下margin重合問題
     ie和ff都存在,相鄰的兩個div的margin-left和margin-right不會重合,可是margin-top和margin-bottom卻會發生重合。

    解決方法,養成良好的代碼編寫習慣,同時採用margin-top或者同時採用margin-bottom。
18.display有哪些值?說明他們的做用。
       block         塊類型。默認寬度爲父元素寬度,可設置寬高,換行顯示。
     none          缺省值。象行內元素類型同樣顯示。
     inline        行內元素類型。默認寬度爲內容寬度,不可設置寬高,同行顯示。
     inline-block  默認寬度爲內容寬度,能夠設置寬高,同行顯示。
     list-item     象塊類型元素同樣顯示,並添加樣式列表標記。
     table         此元素會做爲塊級表格來顯示。
     inherit       規定應該從父元素繼承 display 屬性的值。

19.CSS居中(包括水平居中和垂直居中)
內聯元素居中方案
水平居中設置:
  1.行內元素
    設置 text-align:center;
  2.Flex佈局
    設置display:flex;justify-content:center;(靈活運用,支持Chroime,Firefox,IE9+)
垂直居中設置:
  1.父元素高度肯定的單行文本(內聯元素)
    設置 height = line-height;
  2.父元素高度肯定的多行文本(內聯元素)
    a:插入 table (插入方法和水平居中同樣),而後設置 vertical-align:middle;
    b:先設置 display:table-cell 再設置 vertical-align:middle;
塊級元素居中方案
水平居中設置:
  1.定寬塊狀元素
    設置 左右 margin 值爲 auto;
  2.不定寬塊狀元素
    a:在元素外加入 table 標籤(完整的,包括 table、tbody、tr、td),該元素寫在 td 內,而後設置 margin 的值爲 auto;
    b:給該元素設置 displa:inine 方法;
    c:父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left:50%;
垂直居中設置:
    使用position:absolute(fixed),設置left、top、margin-left、margin-top的屬性;
    利用position:fixed(absolute)屬性,margin:auto這個必須不要忘記了;
    利用display:table-cell屬性使內容垂直居中;
    使用css3的新屬性transform:translate(x,y)屬性;
    使用:before元素;

CSS實現垂直水平居中案例:

一道經典的問題,實現方法有不少種,如下是其中一種實現:
HTML結構:

<div class="wrapper"> <div class="content"></div> </div>

CSS:

.wrapper { position: relative; width: 500px; height: 500px; background-color: #ddd; } .content{ background-color:#6699FF; width:200px; height:200px; position: absolute; //父元素須要相對定位 top: 50%; left: 50%; margin-top:-100px ; //二分之一的height,width margin-left: -100px; }

20.在書寫高效 CSS 時會有哪些問題須要考慮?
reset。參照上題「描述下 「reset」 CSS 文件的做用和使用它的好處」的答案。
規範命名。尤爲對於沒有語義化的html標籤,例如div,所賦予的class值要特別注意。
抽取可重用的部件,注意層疊樣式表的「優先級」。

21.爲何要使用CSS sprites
CSS Sprites其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS的「background-image」,「background-position」的組合進行背景定位,這樣能夠減小不少圖片請求的開銷,由於請求耗時比較長;請求雖然能夠併發,可是若是請求太多會給服務器增長很大的壓力。

22.簡述一下src與href的區別

href 是指向網絡資源所在位置,創建和當前元素(錨點)或當前文檔(連接)之間的連接,用於超連接。

src是指向外部資源的位置,指向的內容將會嵌入到文檔中當前標籤所在位置;在請求src資源時會將其指向的資源下載並應用到文檔內,例如js腳本,img圖片和frame等元素。當瀏覽器解析到該元素時,會暫停其餘資源的下載和處理,直到將該資源加載、編譯、執行完畢,圖片和框架等元素也如此,相似於將所指向資源嵌入當前標籤內。這也是爲何將js腳本放在底部而不是頭部。

23.什麼是CSS Hack?

通常來講是針對不一樣的瀏覽器寫不一樣的CSS,就是 CSS Hack。
IE瀏覽器Hack通常又分爲三種,條件Hack、屬性級Hack、選擇符Hack(詳細參考CSS文檔:css文檔)。例如:

// 一、條件Hack <!--[if IE]> <style> .test{color:red;} </style> <![endif]-->

// 二、屬性Hack .test{ color:#090\9; /* For IE8+ */ *color:#f00; /* For IE7 and earlier */ _color:#ff0; /* For IE6 and earlier */ }

// 三、選擇符Hack * html .test{color:#090;} /* For IE6 and earlier */ * + html .test{color:#ff0;} /* For IE7 */

24.px和em的區別

px和em都是長度單位,區別是,px的值是固定的,指定是多少就是多少,計算比較容易。em得值不是固定的,而且em會繼承父級元素的字體大小。
    瀏覽器的默認字體高都是16px。因此未經調整的瀏覽器都符合: 1em=16px。那麼12px=0.75em, 10px=0.625em

 

JS:

1. 介紹js的基本數據類型
Undefined、Null、Boolean、Number、String

數據類型:2大類:*原始類型*的值和*引用類型*的對象  

    原始類型:值直接保存在變量本地的類型(值爲一個,並且不能特別複雜)

     原始類型5類:Number  String   Boolean  undefined  null

       引用類型:值沒有直接保存在變量本地的類型

                 變量中只保存指向實際數據所在位置的地址值

 

2.js有哪些內置對象?
數據封裝類對象:Object、Array、Boolean、Number 和 String
其餘對象:Function、Arguments、Math、Date、RegExp、Error

3.this對象的理解
this老是指向函數的直接調用者(而非間接調用者);
若是有new關鍵字,this指向new出來的那個對象;
在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this老是指向全局對象Window;

4.談談This對象的理解。
this是js的一個關鍵字,隨着函數使用場合不一樣,this的值會發生變化。
可是有一個總原則,那就是this指的是調用函數的那個對象。
this通常狀況下:是全局對象Global。 做爲方法調用,那麼this就是指這個對象

5.eval是作什麼的?
它的功能是把對應的字符串解析成JS代碼並運行;
應該避免使用eval,不安全,很是耗性能(2次,一次解析成js語句,一次執行)。
由JSON字符串轉換爲JSON對象的時候能夠用eval,var obj =eval('('+ str +')');

6.JavaScript的typeof返回哪些數據類型
Object number function boolean underfind;

7.例舉3種強制類型轉換和2種隱式類型轉換?
強制(parseInt,parseFloat,number)隱式(== – ===);

8.split() join() 的區別
前者是切割成數組的形式,後者是將數組轉換成字符串

9.數組方法pop() push() unshift() shift()
Push()尾部添加 pop()尾部刪除
Unshift()頭部添加 shift()頭部刪除

10.IE和DOM事件流的區別
執行順序不同、
參數不同
事件加不加on
this指向問題

11.IE和標準下有哪些兼容性的寫法
   Var ev = ev || window.event
   document.documentElement.clientWidth || document.body.clientWidth
   Var target = ev.srcElement||ev.target

12.」==」和「===」的不一樣
   前者會自動轉換類型,後者不會

 

13.DOM怎樣添加、移除、移動、複製、建立和查找節點

// 建立新節點

createDocumentFragment()    //建立一個DOM片斷

createElement()   //建立一個具體的元素

createTextNode()   //建立一個文本節點

// 添加、移除、替換、插入

appendChild()

removeChild()

replaceChild()

insertBefore() //在已有的子節點前插入一個新的子節點

// 查找

getElementsByTagName()    //經過標籤名稱

getElementsByName()    //經過元素的Name屬性的值(IE容錯能力較強,會獲得一個數組,其中包括id等於name值的)

getElementById()    //經過元素Id,惟一性

14.null和undefined的區別?
null是一個表示"無"的對象,轉爲數值時爲0;undefined是一個表示"無"的原始值,轉爲數值時爲NaN。
undefined:
(1)變量被聲明瞭,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值爲undefined。
(4)函數沒有返回值時,默認返回undefined。
null:
(1) 做爲函數的參數,表示該函數的參數不是對象。
(2) 做爲對象原型鏈的終點。

15.new操做符具體幹了什麼呢?
(1)建立一個空對象,而且 this 變量引用該對象,同時還繼承了該函數的原型。
(2)屬性和方法被加入到 this 引用的對象中。
(3)新建立的對象由 this 所引用,而且最後隱式的返回 this 。

16.js延遲加載的方式有哪些?


17.call() 和 apply() 的區別和做用?defer和async、動態建立DOM方式(建立script,插入到DOM中,加載完畢後callBack)、按需異步載入js

call vs apply: 都是:在調用方法時,修改當前調用方法的對象

       差異:傳入參數的形式:

         xxx.call(obj,值1,值2,值3....)         

     xxx.apply(obj,[值1,值2,值3....])

   apply()函數有兩個參數:第一個參數是上下文,第二個參數是參數組成的數組。若是上下文是null,則使用全局對象代替。
   如:function.apply(this,[1,2,3]);
   call()的第一個參數是上下文,後續是實例傳入的參數序列。
   如:function.call(this,1,2,3);

 

詳解:

call方法:

語法:call(thisObj,Object)

定義:調用一個對象的一個方法,以另外一個對象替換當前對象。

說明:

call 方法能夠用來代替另外一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。

若是沒有提供 thisObj 參數,那麼 Global 對象被用做 thisObj。

apply方法:

語法:apply(thisObj,[argArray])

定義:應用某一對象的一個方法,用另外一個對象替換當前對象。

說明:

若是 argArray 不是一個有效的數組或者不是 arguments 對象,那麼將致使一個 TypeError。

若是沒有提供 argArray 和 thisObj 任何一個參數,那麼 Global 對象將被用做 thisObj, 而且沒法被傳遞任何參數。

18.什麼是閉包?

閉包:反覆使用局部變量,且保證局部變量不被污染的結構

      什麼時候使用:但願反覆使用局部變量,且保證不被污染時

       缺點:比普通函數佔用更多的內存空間(外層函數的AO)

   如何建立:3步:

        1. 外層函數封裝受保護的局部變量

        2. 外層函數,返回一個操做受保護的局部變量的內層函數對象

        3. 全局由變量調用並保存了外層函數返回的內層函數對象

        結果:只有內層函數有權操做受保護的局部變量

19.說說你對閉包的理解

使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。在js中,函數即閉包,只有函數纔會產生做用域的概念

20.閉包有三個特性:

1.函數嵌套函數

2.內層函數必須使用了外層函數的局部變量

3.外層函數將內層函數返回到外部,可在外部調用

判斷閉包輸出結果:

    1. 找首保護的局部變量

    2. 外層函數被調用幾回,就建立了幾個受保護的變量副本。

    3. 同一次外層函數調用返回的內層函數,總使用統一個局部變量

 

21.棧和隊列的區別?

棧的插入和刪除操做都是在一端進行的,而隊列的操做倒是在兩端進行的。
隊列先進先出,棧先進後出。
棧只容許在表尾一端進行插入和刪除,而隊列只容許在表尾一端進行插入,在表頭一端進行刪除

22.棧和堆的區別?

棧區(stack)—   由編譯器自動分配釋放   ,存放函數的參數值,局部變量的值等。
堆區(heap)   —   通常由程序員分配釋放,   若程序員不釋放,程序結束時可能由OS回收。
堆(數據結構):堆能夠被當作是一棵樹,如:堆排序;
棧(數據結構):一種先進後出的數據結構。

23.defer和async

defer並行加載js文件,會按照頁面上script標籤的順序執行 
async並行加載js文件,下載完成當即執行,不會按照頁面上script標籤的順序執行

24.document.write()的用法

document.write()方法能夠用在兩個方面:頁面載入過程當中用實時腳本建立頁面內容,以及用延時腳本建立本窗口或新窗口的內容。

document.write只能重繪整個頁面。innerHTML能夠重繪頁面的一部分

25.git fetch和git pull的區別

git pull:至關因而從遠程獲取最新版本並merge到本地

git fetch:至關因而從遠程獲取最新版本到本地,不會自動merge

26.attribute和property的區別是什麼?

attributedom元素在文檔中做爲html標籤擁有的屬性;

property就是dom元素在js中做爲對象擁有的屬性。

因此:

對於html的標準屬性來講,attributeproperty是同步的,是會自動更新的,

可是對於自定義的屬性來講,他們是不一樣步的,

27.請解釋一下 JavaScript 的同源策略。

概念:同源策略是客戶端腳本(尤爲是Javascript)的重要的安全度量標準。它最先出自Netscape Navigator2.0,其目的是防止某個文檔或腳本從多個不一樣源裝載。

這裏的同源策略指的是:協議,域名,端口相同,同源策略是一種安全協議。

指一段腳本只能讀取來自同一來源的窗口和文檔的屬性。

說一下什麼是JavaScript的同源策略?
一段腳本只能讀取來自於同一來源的窗口和文檔的屬性,這裏的同一來源指的是主機名、協議和端口號的組合代碼相關的問題。

28.爲何要有同源限制?

咱們舉例說明:好比一個黑客程序,他利用Iframe把真正的銀行登陸頁面嵌到他的頁面上,當你使用真實的用戶名,密碼登陸時,他的頁面就能夠經過Javascript讀取到你的表單中input中的內容,這樣用戶名,密碼就輕鬆到手了。

缺點:

如今網站的JS 都會進行壓縮,一些文件用了嚴格模式,而另外一些沒有。這時這些原本是嚴格模式的文件,被 merge 後,這個串就到了文件的中間,不只沒有指示嚴格模式,反而在壓縮後浪費了字節。

29.事件、IE與火狐的事件機制有什麼區別? 如何阻止冒泡?

    1.咱們在網頁中的某個操做(有的操做對應多個事件)。例如:當咱們點擊一個按鈕就會產生一個事件。是能夠被 JavaScript 偵測到的行爲。
2.事件處理機制:IE是事件冒泡、firefox同時支持兩種事件模型,也就是:捕獲型事件和冒泡型事件。
   3. `ev.stopPropagation()`;注意舊ie的方法 `ev.cancelBubble = true`;

30.事件委託是什麼
讓利用事件冒泡的原理,讓本身的所觸發的事件,讓他的父元素代替執行!

31.請解釋什麼是事件代理

事件代理(Event Delegation),又稱之爲事件委託。是 JavaScript 中經常使用綁定事件的經常使用技巧。顧名思義,「事件代理」便是把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好處是能夠提升性能。

32.談一談JavaScript做用域鏈

做用域鏈的做用是保證執行環境裏有權訪問的變量和函數是有序的,做用域鏈的變量只能向上訪問,變量訪問到window對象即被終止,做用域鏈向下訪問變量是不被容許的。
    當執行一段JavaScript代碼(全局代碼或函數)時,JavaScript引擎會建立爲其建立一個做用域又稱爲執行上下文(Execution Context),在頁面加載後會首先建立一個全局的做用域,而後每執行一個函數,會創建一個對應的做用域,從而造成了一條做用域鏈。每一個做用域都有一條對應的做用域鏈,鏈頭是全局做用域,鏈尾是當前函數做用域。
    做用域鏈的做用是用於解析標識符,當函數被建立時(不是執行),會將this、arguments、命名參數和該函數中的全部局部變量添加到該當前做用域中,當JavaScript須要查找變量X的時候(這個過程稱爲變量解析),它首先會從做用域鏈中的鏈尾也就是當前做用域進行查找是否有X屬性,若是沒有找到就順着做用域鏈繼續查找,直到查找到鏈頭,也就是全局做用域鏈,仍未找到該變量的話,就認爲這段代碼的做用域鏈上不存在x變量,並拋出一個引用錯誤(ReferenceError)的異常。

33.如何理解JavaScript原型鏈
JavaScript中的每一個對象都有一個prototype屬性,咱們稱之爲原型,而原型的值也是一個對象,所以它也有本身的原型,這樣就串聯起來了一條原型鏈,原型鏈的鏈頭是object,它的prototype比較特殊,值爲null。
原型鏈的做用是用於對象繼承,函數A的原型屬性(prototype property)是一個對象,當這個函數被用做構造函數來建立實例時,該函數的原型屬性將被做爲原型賦值給全部對象實例,好比咱們新建一個數組,數組的方法便從數組的原型上繼承而來。
當訪問對象的一個屬性時, 首先查找對象自己, 找到則返回; 若未找到, 則繼續查找其原型對象的屬性(若是還找不到實際上還會沿着原型鏈向上查找, 直至到根). 只要沒有被覆蓋的話, 對象原型的屬性就能在全部的實例中找到,若整個原型鏈未找到則返回undefined

34.JavaScript原型,原型鏈 ? 有什麼特色?
(1)原型對象也是普通的對象,是對象一個自帶隱式的 __proto__ 屬性,原型也有可能有本身的原型,若是一個原型對象的原型不爲null的話,咱們就稱之爲原型鏈。
(2)原型鏈是由一些用來繼承和共享屬性的對象組成的(有限的)對象鏈。

35. 對面向對象的理解

    什麼是面向對象?面向對象就是在程序中,用一個對象描述現實中一個事物

    爲何使用面向對象?由於面向對象更接近於人的思惟方式,更便於代碼維護。

    面向對象三大特色:封裝,繼承,多態

        封裝:講現實中一個事物的屬性和方法,集中定義在程序中的一個對象中。

          爲何要封裝:更接近於人的想法,便於代碼維護。

        繼承:父對象中的成員,子對象能夠直接使用。

          爲何要繼承:代碼重用!節約內存空間

        多態:同同樣東西,在不一樣狀況下表現出不一樣的狀態。

        多態方式:重寫,重載:

          重載:多個同名方法,但參數列表不一樣,調用時,可根據傳入參數的不一樣,動態決定調用何種匹配的方法。

             爲何使用重載:便於調用,減小調用者負擔。

             js語法不支持重載,但可用arguments對象模擬重載效果。

          重寫:子對象以爲父對象的成員很差用,可在本地定義與父對象同名的成員,覆蓋父對象的成員

             爲何使用重寫:專門定義子對象與父對象之間的差別。

35.JavaScript如何實現繼承?
構造繼承
原型繼承
實例繼承
拷貝繼承
原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式。
        function Parent(){
            this.name = 'wang';
        }

        function Child(){
            this.age = 28;
        }
        Child.prototype = new Parent();//繼承了Parent,經過原型
        var demo = new Child();
        alert(demo.age);
        alert(demo.name);//獲得被繼承的屬性

36.javascript裏面的繼承怎麼實現,如何避免原型鏈上面的對象共享
用構造函數和原型鏈的混合模式去實現繼承,避免對象共享能夠參考經典的extend()函數,不少前端框架都有封裝的,就是用一個空函數當作中間變量

37.js繼承方式及其優缺點

①   原型鏈繼承的缺點

一是字面量重寫原型會中斷關係,使用引用類型的原型,而且子類型還沒法給超類型傳遞參數。

②   借用構造函數(類式繼承)

借用構造函數雖然解決了剛纔兩種問題,但沒有原型,則複用無從談起。因此咱們須要原型鏈+借用構造函數的模式,這種模式稱爲組合繼承

③   組合式繼承

組合式繼承是比較經常使用的一種繼承方法,其背後的思路是 使用原型鏈實現對原型屬性和方法的繼承,而經過借用構造函數來實現對實例屬性的繼承。

38.Javascript垃圾回收方法

①  標記清除(mark and sweep)

這是JavaScript最多見的垃圾回收方式,當變量進入執行環境的時候,好比函數中聲明一個變量,垃圾回收器將其標記爲「進入環境」,當變量離開環境的時候(函數執行結束)將其標記爲「離開環境」。

垃圾回收器會在運行的時候給存儲在內存中的全部變量加上標記,而後去掉環境中的變量以及被環境中變量所引用的變量(閉包),在這些完成以後仍存在標記的就是要刪除的變量了

②   引用計數(reference counting)
    在低版本IE中常常會出現內存泄露,不少時候就是由於其採用引用計數方式進行垃圾回收。引用計數的策略是跟蹤記錄每一個值被使用的次數,當聲明瞭一個 變量並將一個引用類型賦值給該變量的時候這個值的引用次數就加1,若是該變量的值變成了另一個,則這個值得引用次數減1,當這個值的引用次數變爲0的時 候,說明沒有變量在使用,這個值無法被訪問了,所以能夠將其佔用的空間回收,這樣垃圾回收器會在運行的時候清理掉引用次數爲0的值佔用的空間。

在IE中雖然JavaScript對象經過標記清除的方式進行垃圾回收,但BOM與DOM對象倒是經過引用計數回收垃圾的, 
    也就是說只要涉及BOM及DOM就會出現循環引用問題。

39.用過哪些設計模式?

①   工廠模式:

主要好處就是能夠消除對象間的耦合,經過使用工程方法而不是new關鍵字。將全部實例化的代碼集中在一個位置防止代碼重複。
   工廠模式解決了重複實例化的問題 ,但還有一個問題,那就是識別問題,由於根本沒法 搞清楚他們究竟是哪一個對象的實例。
function createObject(name,age,profession){//集中實例化的函數var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.profession = profession;
    obj.move = function () {
        return this.name + ' at ' + this.age + ' engaged in ' + this.profession;
    };
    return obj;
}
var test1 = createObject('trigkit4',22,'programmer');//第一個實例var test2 = createObject('mike',25,'engineer');//第二個實例

②   構造函數模式

使用構造函數的方法 ,即解決了重複實例化的問題 ,又解決了對象識別的問題,該模式與工廠模式的不一樣之處在於:

1.構造函數方法沒有顯示的建立對象 (new Object());
2.直接將屬性和方法賦值給 this 對象;
3.沒有 renturn 語句。

40.javascript對象的幾種建立方式

1,工廠模式
2,構造函數模式
3,原型模式
4,混合構造函數和原型模式
5,動態原型模式
6,寄生構造函數模式
7,穩妥構造函數模式
41.Javascript中callee和caller的做用?

caller是返回一個對函數的引用,該函數調用了當前函數;

callee是返回正在被執行的function函數,也就是所指定的function對象的正文。

42.請描述一下cookies,sessionStorage和localStorage的區別

sessionStorage用於本地存儲一個會話(session)中的數據,這些數據只有在同一個會話中的頁面才能訪問而且當會話結束後數據也隨之銷燬。所以sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。而localStorage用於持久化的本地存儲,除非主動刪除數據,不然數據是永遠不會過時的。

web storage和cookie的區別

Web Storage的概念和cookie類似,區別是它是爲了更大容量存儲設計的。Cookie的大小是受限的,而且每次你請求一個新的頁面的時候Cookie都會被髮送過去,這樣無形中浪費了帶寬,另外cookie還須要指定做用域,不能夠跨域調用。
    除此以外,Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie須要前端開發者本身封裝setCookie,getCookie。可是Cookie也是不能夠或缺的:Cookie的做用是與服務器進行交互,做爲HTTP規範的一部分而存在 ,而Web Storage僅僅是爲了在本地「存儲」數據而生。

43.跨域請求資源的方法有哪些?

因爲瀏覽器同源策略,凡是發送請求 URL 的協議、域名、端口三者之間任意一與當前頁面地址不一樣即爲跨域。

(1)JSONP(jsonp 跨域 get 請求) 

這種方式主要是經過動態建立一個 script 標籤,瀏覽器對 script 的資源引用沒有同源限制,同時資源加載到頁面後會當即執行;(建立 script 標籤向不一樣域提交 http 請求的不會被拒絕的方法,jsonp 標籤的 src 屬性是沒有跨域限制的)

實際項目中 JSONP 一般用來獲取 json 格式數據,這時先後端一般約定一個參數 callback,該參數的值,就是處理返回數據的函數名稱;

缺點:這種方式沒法發送 post 請求,另外要肯定 jsonp 的請求是否失敗並不容易,大多數框架的實現都是結合超時時間來判斷。

(2)proxy 代理

這種方式首先將請求發送給後臺服務器,經過服務器來發送請求,而後將請求的結果傳遞給前端;

須要注意的是若是你代理的是 https 協議的請求,那麼你的 proxy 首先須要信任該證書或者忽略證書檢查,不然你的請求沒法成功。

(3)cors

當你使用 XMLHttpRequest 發送請求時,瀏覽器發現該請求不符合同源策略,會給該請求頭 origin,後臺進行一系列處理,若是肯定接受請求則在返回結果加入一個響應頭 Access-Control-Allow-Origin;瀏覽器判斷該響應頭中是否包含 Origin 的值,若是有則瀏覽器會處理響應,咱們就能夠拿到響應數據,若是不包含瀏覽器直接駁回,這時咱們沒法拿到響應數據; 

post 請求的 content-type 不是常規的三個:application/x-www-form-urlencoded(使用 HTTP 的 post 方式提交表單)、multipart/form-data(同上,但主要用於表單提交時伴隨文件上傳的場合)、text/plain(純文本)

post 請求的 payload 爲 text/html 

payload 指在 http 中,應該是 post 請求時所攜帶的有效數據;

有一種跨域須要特別注意就是 https 協議下發送 https 請求,除了使用 proxy 代理外其餘方法都無解,會被瀏覽器直接 block 掉。

44.淺談MVC,MVP和 MVVM

 1.MVC

    ①.MVC模式的意思是,軟件能夠分紅三個部分。

視圖(View):用戶界面。

控制器(Controller):業務邏輯

模型(Model):數據保存

         各部分之間通訊方式以下:

 View 傳送指令到 Controller

            Controller 完成業務邏輯後,要求 Model 改變狀態

Model 將新的數據發送到 View,用戶獲得反饋

 

②.互動模式

接受用戶指令時,MVC 能夠分紅兩種方式。一種是經過 View 接受指令,傳遞給 Controller。

另外一種是直接經過controller接受指令。

③   實例:Backbone

實際項目每每採用更靈活的方式,以 Backbone.js 爲例。

1. 用戶能夠向 View 發送指令(DOM 事件),再由 View 直接要求 Model 改變狀態。

2. 用戶也能夠直接向 Controller 發送指令(改變 URL 觸發 hashChange 事件),再由 Controller 發送給 View。

3. Controller 很是薄,只起到路由的做用,而 View 很是厚,業務邏輯都部署在 View。因此,Backbone 索性取消了 Controller,只保留一個 Router(路由器) 。

2、MVP

MVP 模式將 Controller 更名爲 Presenter,同時改變了通訊方向。

1. 各部分之間的通訊,都是雙向的。

2. View 與 Model 不發生聯繫,都經過 Presenter 傳遞。

3. View 很是薄,不部署任何業務邏輯,稱爲"被動視圖"(Passive View),即沒有任何主動性,而 Presenter很是厚,全部邏輯都部署在那裏。

3、MVVM

MVVM 模式將 Presenter 更名爲 ViewModel,基本上與 MVP 模式徹底一致。

惟一的區別是,它採用雙向綁定(data-binding):View的變更,自動反映在 ViewModel,反之亦然。Angular 和 Ember 都採用這種模式。

 

1.ajax的原理

在舊的交互方式中,由用戶觸發一個HTTP請求到服務器,服務器對其進行處理後再返回一個新的HTHL頁到客戶端, 每當服務器處理客戶端提交的請求時,客戶都只能空閒等待,而且哪怕只是一次很小的交互、只需從服務器端獲得很簡單的一個數據,都要返回一個完整的HTML頁,而用戶每次都要浪費時間和帶寬去從新讀取整個頁面。而使用Ajax後用戶從感受上幾乎全部的操做都會很快響應沒有頁面重載(白屏)的等待。

Ajax的原理簡單來講是在用戶和服務器之間加了—箇中間層(AJAX引擎),經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。使用戶操做與服務器響應異步化。這其中最關鍵的一步就是從服務器得到請求數據。

Ajax的過程只涉及JavaScript、XMLHttpRequest和DOM。XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript能夠及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

2.簡述同步和異步的區別

同步是阻塞模式,異步是非阻塞模式。
同步就是指一個進程在執行某個請求的時候,若該請求須要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去;
異步是指進程不須要一直等下去,而是繼續執行下面的操做,無論其餘進程的狀態。當有消息返回時系統會通知進程進行處理,這樣能夠提升執行的效率。

 

1.建立ajax過程

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

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

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

(4)發送HTTP請求.

(5)獲取異步調用返回的數據.

(6)使用JavaScript和DOM實現局部刷新.

        var xmlHttp = new XMLHttpRequest();

        xmlHttp.open('GET','demo.php','true');

        xmlHttp.send()

        xmlHttp.onreadystatechange = function(){

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

    }

2.ajax的缺點和在IE下的問題?

①ajax的缺點

  1、ajax不支持瀏覽器back按鈕。
  2、安全問題 AJAX暴露了與服務器交互的細節。
  3、對搜索引擎的支持比較弱。
  4、破壞了程序的異常機制。
  5、不容易調試。

②IE緩存問題

在IE瀏覽器下,若是請求的方法是GET,而且請求的URL不變,那麼這個請求的結果就會被緩存。解決這個問題的辦法能夠經過實時改變請求的URL,只要URL改變,就不會被緩存,能夠經過在URL末尾添加上隨機的時間戳參數('t'= + new Date().getTime())

或者:open('GET','demo.php?rand=+Math.random()',true);//

  • 3.ajax 有那些優缺點?如何解決跨域問題?
    (Q1)
    優勢:
    (1)經過異步模式,提高了用戶體驗.
    (2)優化了瀏覽器和服務器之間的傳輸,減小沒必要要的數據往返,減小了帶寬佔用.
    (3)Ajax在客戶端運行,承擔了一部分原本由服務器承擔的工做,減小了大用戶量下的服務器負載。
    (4)Ajax能夠實現動態不刷新(局部刷新)
    缺點:
    (1)安全問題 AJAX暴露了與服務器交互的細節。
    (2)對搜索引擎的支持比較弱。
    (3)不容易調試。
    (Q2)jsonp、 iframe、window.name、window.postMessage、服務器上設置代理頁面。

4..GET和POST的區別,什麼時候使用POST?
     GET:通常用於信息獲取,使用URL傳遞參數,對所發送信息的數量也有限制,通常在2000個字符
     POST:通常用於修改服務器上的資源,對所發送的信息沒有限制。
     GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值,
    也就是說Get是經過地址欄來傳值,而Post是經過提交表單來傳值。
    然而,在如下狀況中,請使用 POST 請求:
    沒法使用緩存文件(更新服務器上的文件或數據庫)
    向服務器發送大量數據(POST 沒有數據量限制)
    發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

5.ajax請求時,如何解釋json數據
  使用eval parse,鑑於安全性考慮 使用parse更靠譜;

6.異步加載和延遲加載

1.異步加載的方案: 動態插入script標籤
2.經過ajax去獲取js代碼,而後經過eval執行
3.script標籤上添加defer或者async屬性
4.建立並插入iframe,讓它異步執行js
5.延遲加載:有些 js 代碼並非頁面初始化的時候就馬上須要的,而稍後的某些狀況才須要的。

7.Ajax請求的頁面歷史記錄狀態問題

能夠經過錨點來記錄狀態,location.hash。讓瀏覽器記錄Ajax請求時頁面狀態的變化。

還能夠經過HTML5history.pushState,來實現瀏覽器地址欄的無刷新改變

 

 

 

HTTP&JSON:

一次完整的HTTP事務是怎樣的一個過程?

基本流程:

a. 域名解析

b. 發起TCP的3次握手

c. 創建TCP鏈接後發起http請求

d. 服務器端響應http請求,瀏覽器獲得html代碼

e. 瀏覽器解析html代碼,並請求html代碼中的資源

f. 瀏覽器對頁面進行渲染呈現給用戶

1.HTTP狀態碼知道哪些?
100  Continue  繼續,通常在發送post請求時,已發送了http header以後服務端將返回此信息,表示確認,以後發送具體參數信息
200  OK   正常返回信息
201  Created  請求成功而且服務器建立了新的資源
202  Accepted  服務器已接受請求,但還沒有處理
301  Moved Permanently  請求的網頁已永久移動到新位置。
302 Found  臨時性重定向。
303 See Other  臨時性重定向,且老是使用 GET 請求新的 URI。
304  Not Modified  自從上次請求後,請求的網頁未修改過。
400 Bad Request  服務器沒法理解請求的格式,客戶端不該當嘗試再次使用相同的內容發起請求。
401 Unauthorized  請求未受權。
403 Forbidden  禁止訪問。
404 Not Found  找不到如何與 URI 相匹配的資源。
500 Internal Server Error  最多見的服務器端錯誤。
503 Service Unavailable 服務器端暫時沒法處理請求(多是過載或維護)。

2.HTTP和HTTPS

HTTP協議一般承載於TCP協議之上,在HTTPTCP之間添加一個安全協議層(SSLTSL),這個時候,就成了咱們常說的HTTPS。

默認HTTP的端口號爲80,HTTPS的端口號爲443。

3.爲何HTTPS安全

由於網絡請求須要中間有不少的服務器路由器的轉發。中間的節點均可能篡改信息,而若是使用HTTPS,密鑰在你和終點站纔有。https之因此比http安全,是由於他利用ssl/tls協議傳輸。它包含證書,卸載,流量轉發,負載均衡,頁面適配,瀏覽器適配,refer傳遞等。保障了傳輸過程的安全性

4.關於Http 2.0 你知道多少?

HTTP/2引入了「服務端推(server push)」的概念,它容許服務端在客戶端須要數據以前就主動地將數據發送到客戶端緩存中,從而提升性能。

HTTP/2提供更多的加密支持

HTTP/2使用多路技術,容許多個消息在一個鏈接上同時交差。

它增長了頭壓縮(header compression),所以即便很是小的請求,其請求和響應的header都只會佔用很小比例的帶寬。

5.一個頁面從輸入 URL 到頁面加載顯示完成,這個過程當中都發生了什麼?
(1)查找瀏覽器緩存
(2)DNS解析、查找該域名對應的IP地址、重定向(301)、發出第二個GET請求
(3)進行HTTP協議會話
(4)客戶端發送報頭(請求報頭)
(5)服務器回饋報頭(響應報頭)
(6)html文檔開始下載
(7)文檔樹創建,根據標記請求所需指定MIME類型的文件
(8)文件顯示

6.JSON 的瞭解?
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它是基於JavaScript的一個子集。數據格式簡單, 易於讀寫, 佔用帶寬小。
格式:採用鍵值對,例如:{'age':'12', 'name':'back'}

7.XMLJSON的區別?

(1).數據體積方面。

JSON相對於XML來說,數據的體積小,傳遞的速度更快些。

(2).數據交互方面。

JSON與JavaScript的交互更加方便,更容易解析處理,更好的數據交互。

(3).數據描述方面。

JSON對數據的描述性比XML較差。

(4).傳輸速度方面。

JSON的速度要遠遠快於XML。

8.如何解決跨域問題

①   JSONP:

原理是:動態插入script標籤,經過script標籤引入一個js文件,這個js文件載入成功後會執行咱們在url參數中指定的函數,而且會把咱們須要的json數據做爲參數傳入。

因爲同源策略的限制,XmlHttpRequest只容許請求當前源(域名、協議、端口)的資源,爲了實現跨域請求,能夠經過script標籤實現跨域請求,而後在服務端輸出JSON數據並執行回調函數,從而解決了跨域的數據請求。

優勢是兼容性好,簡單易用,支持瀏覽器與服務器雙向通訊。缺點是隻支持GET請求。

JSONPjson+padding(內填充),顧名思義,就是把JSON填充到一個盒子裏

<script>

    function createJs(sUrl){

        var oScript = document.createElement('script');

        oScript.type = 'text/javascript';

        oScript.src = sUrl;

        document.getElementsByTagName('head')[0].appendChild(oScript);

    }

    createJs('jsonp.js');

    box({

       'name': 'test'

    });

    function box(json){

        alert(json.name);

    }

</script>

   

②   CORS

服務器端對於CORS的支持,主要就是經過設置Access-Control-Allow-Origin來進行的。若是瀏覽器檢測到相應的設置,就能夠容許Ajax進行跨域的訪問

③   經過修改document.domain來跨子域

將子域和主域的document.domain設爲同一個主域.前提條件:這兩個域名必須屬於同一個基礎域名!並且所用的協議,端口都要一致,不然沒法利用document.domain進行跨域

主域相同的使用document.domain

④   使用window.name來進行跨域

window對象有個name屬性,該屬性有個特徵:即在一個窗口(window)的生命週期內,窗口載入的全部的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的全部頁面中的

⑤   使用HTML5中新引進的window.postMessage方法來跨域傳送數據

還有flash、在服務器上設置代理頁面等跨域方式。我的認爲window.name的方法既不復雜,也能兼容到幾乎全部瀏覽器,這真是極好的一種跨域方法。

 

其餘:

1. 經常使用那幾種瀏覽器測試?有哪些內核(Layout Engine)?
   (1)
瀏覽器:IEChromeFireFoxSafariOpera
   (2)
內核:TridentGeckoPrestoWebkit

2.頁面的哪些瀏覽器你測試過,分別內核是什麼?

IE(IE內核),火狐(Gecko),谷歌(webkit),opera(presto)

3.常見的瀏覽器內核有哪些?
Trident內核:IE,MaxThon,TT,The World,360,搜狗瀏覽器等。[又稱MSHTML]
Gecko
內核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey
Presto
內核:Opera7及以上。 [Opera內核原爲:Presto,現爲:Blink;]
Webkit
內核:Safari,Chrome等。 [ Chrome的:BlinkWebKit的分支)]

4.介紹一下你對瀏覽器內核的理解?
  
主要分紅兩部分:渲染引擎(layout engineerRendering Engine)JS引擎。
  
渲染引擎:負責取得網頁的內容(HTMLXML、圖像等等)、整理訊息(例如加入CSS等),以及計算網頁的顯示方式,而後會輸出至顯示器或打印機。瀏覽器的內核的不一樣對於網頁的語法解釋會有不一樣,因此渲染的效果也不相同。全部網頁瀏覽器、電子郵件客戶端以及其它須要編輯、顯示網絡內容的應用程序都須要內核。
    JS
引擎則:解析和執行javascript來實現網頁的動態效果。
   
最開始渲染引擎和JS引擎並無區分的很明確,後來JS引擎愈來愈獨立,內核就傾向於只指渲染引擎。

5.如何實現瀏覽器內多個標籤頁之間的通訊?
WebSocket
SharedWorker
也能夠調用localstorgecookies等本地存儲方式。
localstorge
另外一個瀏覽上下文裏被添加、修改或刪除時,它都會觸發一個事件,咱們經過監聽事件,控制它的值來進行頁面信息通訊。
注意quirksSafari 在無痕模式下設置localstorge值時會拋出 QuotaExceededError 的異常。

6.web標準以及w3c的理解和認識

:標籤閉合,標籤小寫,不亂嵌套,提升搜索機器人搜索概率。使用外鏈cssjs腳本,結構行爲表現分離,內容能被更多普遍的設備所訪問,更少的代碼和組件,容易維護,改版方便,不須要變更頁面內容。

7.前端頁面有哪三層構成,分別是什麼,做用是什麼?

結構層:html 表示層:css 行爲層:js

8.線程與進程的區別
一個程序至少有一個進程,一個進程至少有一個線程. 
線程的劃分尺度小於進程,使得多線程程序的併發性高。 
另外,進程在執行過程當中擁有獨立的內存單元,而多個線程共享內存,從而極大地提升了程序的運行效率。 
線程在執行過程當中與進程仍是有區別的。每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。 
從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分能夠同時執行。但操做系統並無將多個線程看作多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

9.BFC規範的理解?

BFC,塊級格式化上下文,一個建立了新的BFC的盒子是獨立佈局的,盒子裏面的子元素的樣式不會影響到外面的元素。在同一個BFC中的兩個毗鄰的塊級盒在垂直方向(和佈局方向有關係)的margin會發生摺疊。
   W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行佈局,以及與其餘元素的關係和相互做用。

10.請描述一下 cookiessessionStorage localStorage 的區別?
cookie
在瀏覽器和服務器間來回傳遞。 sessionStoragelocalStorage不會
sessionStorage
localStorage的存儲空間更大;
sessionStorage
localStorage有更多豐富易用的接口;
sessionStorage
localStorage各自獨立的存儲空間;

詳細解釋:

cookie是網站爲了標示用戶身份而儲存在用戶本地終端(Client Side)上的數據(一般通過加密)。
cookie
數據始終在同源的http請求中攜帶(即便不須要),記會在瀏覽器和服務器間來回傳遞。
sessionStorage
localStorage不會自動把數據發給服務器,僅在本地保存。
存儲大小:
cookie
數據大小不能超過4k
sessionStorage
localStorage 雖然也有存儲大小的限制,但比cookie大得多,能夠達到5M或更大。
有期時間:
localStorage   
存儲持久數據,瀏覽器關閉後數據不丟失除非主動刪除數據;
sessionStorage  
數據在當前瀏覽器窗口關閉後自動刪除。
cookie         
設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉

11.常見web安全及防禦原理

  sql注入原理

就是經過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。

總的來講有如下幾點:

          1.永遠不要信任用戶的輸入,要對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度,對單引號和雙"-"進行轉換等。

          2.永遠不要使用動態拼裝SQL,能夠使用參數化的SQL或者直接使用存儲過程進行數據查詢存取。

          3.永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。

4.不要把機密信息明文存放,請加密或者hash掉密碼和敏感的信息。

  XSS原理及防範

Xss(cross-site scripting)攻擊指的是攻擊者往Web頁面裏插入惡意 html標籤或者JavaScript代碼。好比:攻擊者在論壇中放一個看似安全的連接,騙取用戶點擊後,竊取cookie中的用戶私密信息;或者攻擊者在論壇中加一個惡意表單,當用戶提交表單的時候,卻把信息傳送到攻擊者的服務器中,而不是用戶本來覺得的信任站點。

  XSS防範方法

首先代碼裏對用戶輸入的地方和變量都須要仔細檢查長度和對」<」,」>」,」;」,」’」等字符作過濾;其次任何內容寫到頁面以前都必須加以encode,避免不當心把html tag 弄出來。這一個層面作好,至少能夠堵住超過一半的XSS 攻擊。

首先,避免直接在cookie 中泄露用戶隱私,例如email、密碼等等。

其次,經過使cookie 和系統ip 綁定來下降cookie 泄露後的危險。這樣攻擊者獲得的cookie 沒有實際價值,不可能拿來重放。

若是網站不須要再瀏覽器端對cookie 進行操做,能夠在Set-Cookie 末尾加上HttpOnly 來防止javascript 代碼直接獲取cookie 

儘可能採用POST 而非GET 提交表單

  XSSCSRF有什麼區別嗎?

XSS是獲取信息,不須要提早知道其餘用戶頁面的代碼和數據包。CSRF是代替用戶完成指定的動做,須要知道其餘用戶頁面的代碼和數據包。

要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:

登陸受信任網站A,並在本地生成Cookie

在不登出A的狀況下,訪問危險網站B

  CSRF的防護

服務端的CSRF方式方法不少樣,但總的思想都是一致的,就是在客戶端頁面增長僞隨機數。

經過驗證碼的方法

12.Web Worker webSocket

worker主線程:

    1.經過 worker = new Worker( url ) 加載一個JS文件來建立一個worker,同時返回一個worker實例。

    2.經過worker.postMessage( data ) 方法來向worker發送數據。

    3.綁定worker.onmessage方法來接收worker發送過來的數據。

4.能夠使用 worker.terminate() 來終止一個worker的執行。

WebSocketWeb應用程序的傳輸協議,它提供了雙向的,按序到達的數據流。他是一個Html5協議,WebSocket的鏈接是持久的,他經過在客戶端和服務器之間保持雙工鏈接,服務器的更新能夠被及時推送給客戶端,而不須要客戶端以必定時間間隔去輪詢。

13.談談你對webpack的見解

WebPack 是一個模塊打包工具,你能夠使用WebPack管理你的模塊依賴,並編繹輸出模塊們所需的靜態文件。它可以很好地管理、打包Web開發中所用到的HTMLJavaScriptCSS以及各類靜態文件(圖片、字體等),讓開發過程更加高效。對於不一樣類型的資源,webpack有對應的模塊加載器。webpack模塊打包器會分析模塊間的依賴關係,最後 生成了優化且合併後的靜態資源。

webpack的兩大特點:

         1.code splitting(能夠自動完成)
         2.loader 能夠處理各類類型的靜態文件,而且支持串聯操做

webpack 是以commonJS的形式來書寫腳本滴,但對 AMD/CMD 的支持也很全面,方便舊項目進行代碼遷移。

webpack具備requireJsbrowserify的功能,但仍有不少本身的新特性:

1. CommonJS AMD ES6的語法作了兼容

2. jscss、圖片等資源文件都支持打包

3. 串聯式模塊加載器以及插件機制,讓其具備更好的靈活性和擴展性,例如提供對CoffeeScriptES6的支持

4. 有獨立的配置文件webpack.config.js

5. 能夠將代碼切割成不一樣的chunk,實現按需加載,下降了初始化時間

6. 支持 SourceUrls SourceMaps,易於調試

7. 具備強大的Plugin接口,大可能是內部插件,使用起來比較靈活

8.webpack 使用異步 IO 並具備多級緩存。這使得 webpack 很快且在增量編譯上更加快

14.WEB應用從服務器主動推送Data到客戶端有那些方式?

Javascript數據推送

Commet:基於HTTP長鏈接的服務器推送技術

基於WebSocket的推送方案

SSEServer-Send Event):服務器推送數據新方式

15.說說你對AMDCommonjs的理解

CommonJS是服務器端模塊的規範,Node.js採用了這個規範。CommonJS規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操做。AMD規範則是非同步加載模塊,容許指定回調函數。

AMD推薦的風格經過返回一個對象作爲模塊對象,CommonJS的風格經過對module.exportsexports的屬性賦值來達到暴露模塊對象的目的。

16.如何刪除一個cookie

  將時間設爲當前時間往前一點。

var date = newDate();

date.setDate(date.getDate() - 1);//真正的刪除

setDate()方法用於設置一個月的某一天。

  expires的設置

document.cookie = 'user='+ encodeURIComponent('name')  + ';expires = ' + newDate(0)

17.請你談談Cookie的弊端

cookie雖然在持久保存客戶端數據提供了方便,分擔了服務器存儲的負擔,但仍是有不少侷限性的。

第一:每一個特定的域名下最多生成20cookie

1.IE6或更低版本最多20cookie
2.IE7和以後的版本最後能夠有50cookie
3.Firefox最多50cookie
4.chromeSafari沒有作硬性限制

IEOpera 會清理近期最少使用的cookieFirefox會隨機清理cookie

cookie的最大大約爲4096字節,爲了兼容性,通常不能超過4095字節。

IE 提供了一種存儲能夠持久化用戶數據,叫作userdata,從IE5.0就開始支持。每一個數據最多128K,每一個域名下最多1M。這個持久化數據放在緩存中,若是緩存沒有清理,那麼會一直存在。

  優勢:極高的擴展性和可用性

1.經過良好的編程,控制保存在cookie中的session對象的大小。
2.經過加密和安全傳輸技術(SSL),減小cookie被破解的可能性。
3.只在cookie中存放不敏感數據,即便被盜也不會有重大損失。
4.控制cookie的生命期,使之不會永遠有效。偷盜者極可能拿到一個過時的cookie

②缺點:

1.`Cookie`數量和長度的限制。每一個domain最多隻能有20cookie,每一個cookie長度不能超過4KB,不然會被截掉.
2.安全性問題。若是cookie被人攔截了,那人就能夠取得全部的session信息。即便加密也與事無補,由於攔截者並不須要知道cookie的意義,他只要原樣轉發cookie就能夠達到目的了。
3.有些狀態不可能保存在客戶端。例如,爲了防止重複提交表單,咱們須要在服務器端保存一個計數器。若是咱們把這個計數器保存在客戶端,那麼它起不到任何做用。

18.瀏覽器本地存儲

在較高版本的瀏覽器中,js提供了sessionStorageglobalStorage。在HTML5中提供了localStorage來取代globalStorage

html5中的Web Storage包括了兩種存儲方式:sessionStoragelocalStorage

sessionStorage用於本地存儲一個會話(session)中的數據,這些數據只有在同一個會話中的頁面才能訪問而且當會話結束後數據也隨之銷燬。所以sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。

localStorage用於持久化的本地存儲,除非主動刪除數據,不然數據是永遠不會過時的。

你所瞭解到的Web攻擊技術:

1XSSCross-Site Scripting,跨站腳本攻擊):指經過存在安全漏洞的Web網站註冊用戶的瀏覽器內運行非法的HTML標籤或者JavaScript進行的一種攻擊。
   
2SQL注入攻擊
   
3CSRFCross-Site Request Forgeries,跨站點請求僞造):指攻擊者經過設置好的陷阱,強制對已完成的認證用戶進行非預期的我的信息或設定信息等某些狀態更新。

 

19.web storagecookie的區別

Web Storage的概念和cookie類似,區別是它是爲了更大容量存儲設計的。Cookie的大小是受限的,而且每次你請求一個新的頁面的時候Cookie都會被髮送過去,這樣無形中浪費了帶寬,另外cookie還須要指定做用域,不能夠跨域調用。

除此以外,Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie須要前端開發者本身封裝setCookiegetCookie

可是cookie也是不能夠或缺的:cookie的做用是與服務器進行交互,做爲HTTP規範的一部分而存在 ,而Web Storage僅僅是爲了在本地「存儲」數據而生

瀏覽器的支持除了IE及如下不支持外,其餘標準瀏覽器都徹底支持(ieFF需在web服務器裏運行),值得一提的是IE老是辦好事,例如IE7IE6中的userData其實就是javascript本地存儲的解決方案。經過簡單的代碼封裝能夠統一到全部的瀏覽器都支持web storage

localStoragesessionStorage都具備相同的操做方法,例如setItemgetItemremoveItem

20.cookie session 的區別:

    1cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
    2cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙
       考慮到安全應當使用session
    3session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
        考慮到減輕服務器性能方面,應當使用COOKIE
    4、單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20cookie
5、因此我的建議:
       將登錄信息等重要信息存放爲SESSION
       其餘信息若是須要保留,能夠放在COOKIE

21.哪些操做會形成內存泄漏?

內存泄漏指任何對象在您再也不擁有或須要它以後仍然存在。
垃圾回收器按期掃描對象,並計算引用了每一個對象的其餘對象的數量。若是一個對象的引用數量爲 0(沒有其餘對象引用過該對象),或對該對象的唯一引用是循環的,那麼該對象的內存便可回收。
setTimeout 的第一個參數使用字符串而非函數的話,會引起內存泄漏。
閉包、控制檯日誌、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)

22.對前端模塊化的認識

AMD  RequireJS 在推廣過程當中對模塊定義的規範化產出。

CMD  SeaJS 在推廣過程當中對模塊定義的規範化產出。

AMD 是提早執行,CMD 是延遲執行。

AMD推薦的風格經過返回一個對象作爲模塊對象,CommonJS的風格經過對module.exportsexports的屬性賦值來達到暴露模塊對象的目的。

CMD模塊方式

define(function(require, exports, module) {

                // 模塊代碼

    });

23.你有哪些性能優化的方法?
1) 減小http請求次數:CSS Sprites, JSCSS源碼壓縮、圖片大小控制合適;網頁GzipCDN託管,data緩存 ,圖片服務器。
2) 前端模板 JS+數據,減小因爲HTML標籤致使的帶寬浪費,前端用變量保存AJAX請求結果,每次操做本地變量,不用請求,減小請求次數
3) 用innerHTML代替DOM操做,減小DOM操做次數,優化javascript性能。
4) 當須要設置的樣式不少時設置className而不是直接操做style
5) 少用全局變量、緩存DOM節點查找的結果。減小IO讀取操做。
6) 避免使用CSS Expressioncss表達式)又稱Dynamic properties(動態屬性)
7) 圖片預加載,將樣式表放在頂部,將腳本放在底部  加上時間戳。

24.談談性能優化問題

代碼層面:避免使用css表達式,避免使用高級選擇器,通配選擇器。

緩存利用:緩存Ajax,使用CDN,使用外部jscss文件以便緩存,添加Expires頭,服務端配置Etag,減小DNS查找等

請求數量:合併樣式和腳本,使用css圖片精靈,初始首屏以外的圖片資源按需加載,靜態資源延遲加載。

請求帶寬:壓縮文件,開啓GZIP

   代碼層面的優化

1.hash-table來優化查找

2.少用全局變量

3.innerHTML代替DOM操做,減小DOM操做次數,優化javascript性能

4.setTimeout來避免頁面失去響應

5.緩存DOM節點查找的結果

6.避免使用CSS Expression

7.避免全局查詢

8.避免使用with(with會建立本身的做用域,會增長做用域鏈長度)

9.多個變量聲明合併

10.避免圖片和iFrame等的空Src。空Src會從新加載當前頁面,影響速度和效率

11.儘可能避免寫在HTML標籤中寫Style屬性

25.移動端性能優化

1.儘可能使用css3動畫,開啓硬件加速。

2.適當使用touch事件代替click事件。

3.避免使用css3漸變陰影效果。

4.能夠用transform: translateZ(0)來開啓硬件加速。

5.不濫用FloatFloat在渲染時計算量比較大,儘可能減小使用

6.不濫用Web字體。Web字體須要下載,解析,重繪當前頁面,儘可能減小使用。

7.合理使用requestAnimationFrame動畫代替setTimeout

8.CSS中的屬性(CSS3 transitionsCSS3 3D transformsOpacityCanvasWebGLVideo)會觸發GPU渲染,請合理使用。過渡使用會引起手機過耗電增長

9.PC端的在移動端一樣適用

26.什麼是Etag

當發送一個服務器請求時,瀏覽器首先會進行緩存過時判斷。瀏覽器根據緩存過時時間判斷緩存文件是否過時。

情景一:若沒有過時,則不向服務器發送請求,直接使用緩存中的結果,此時咱們在瀏覽器控制檯中能夠看到 200 OK(from cache) ,此時的狀況就是徹底使用緩存,瀏覽器和服務器沒有任何交互的。

情景二:若已過時,則向服務器發送請求,此時請求中會帶上①中設置的文件修改時間,和Etag

而後,進行資源更新判斷。服務器根據瀏覽器傳過來的文件修改時間,判斷自瀏覽器上一次請求以後,文件是否是沒有被修改過;根據Etag,判斷文件內容自上一次請求以後,有沒有發生變化

情形一:若兩種判斷的結論都是文件沒有被修改過,則服務器就不給瀏覽器發index.html的內容了,直接告訴它,文件沒有被修改過,你用你那邊的緩存吧—— 304 Not Modified,此時瀏覽器就會從本地緩存中獲取index.html的內容。此時的狀況叫協議緩存,瀏覽器和服務器之間有一次請求交互。

情形二:若修改時間和文件內容判斷有任意一個沒有經過,則服務器會受理這次請求,以後的操做同①

    只有get請求會被緩存,post請求不會

27.ETag應用:

Etag由服務器端生成,客戶端經過If-Match或者說If-None-Match這個條件判斷請求來驗證資源是否修改。常見的是使用If-None-Match。請求一個文件的流程可能以下:

====第一次請求===

1.客戶端發起 HTTP GET 請求一個文件;
2.服務器處理請求,返回文件內容和一堆Header,固然包括Etag(例如"2e681a-6-5d044840")(假設服務器支持Etag生成和已經開啓了Etag).狀態碼200

====第二次請求===

客戶端發起 HTTP GET 請求一個文件,注意這個時候客戶端同時發送一個If-None-Match頭,這個頭的內容就是第一次請求時服務器返回的Etag2e681a-6-5d0448402.服務器判斷髮送過來的Etag和計算出來的Etag匹配,所以If-None-MatchFalse,不返回200,返回304,客戶端繼續使用本地緩存;流程很簡單,問題是,若是服務器又設置了Cache-Control:max-ageExpires呢,怎麼辦

答案是同時使用,也就是說在徹底匹配If-Modified-SinceIf-None-Match即檢查完修改時間和Etag以後,

服務器才能返回304.(不要陷入到底使用誰的問題怪圈)

28.爲何使用Etag請求頭?

Etag 主要爲了解決 Last-Modified 沒法解決的一些問題。

29.ExpiresCache-Control

Expires要求客戶端和服務端的時鐘嚴格同步。HTTP1.1引入Cache-Control來克服Expires頭的限制。若是max-ageExpires同時出現,則max-age有更高的優先級。

    Cache-Control: no-cache, private, max-age=0

    ETag: abcde

    Expires: Thu, 15 Apr 201420:00:00 GMT

    Pragma: private

Last-Modified: $now // RFC1123 format

30.ES6的瞭解

新增模板字符串(爲JavaScript提供了簡單的字符串插值功能)、箭頭函數(操做符左邊爲輸入的參數,而右邊則是進行的操做以及返回的值Inputs=>outputs。)、for-of(用來遍歷數據—例如數組中的值。)   arguments對象可被不定參數和默認參數完美代替。ES6promise對象歸入規範,提供了原生的Promise對象。增長了letconst命令,用來聲明變量。增長了塊級做用域。let命令實際上就增長了塊級做用域。ES6規定,var命令和function命令聲明的全局變量,屬於全局對象的屬性;let命令、const命令、class命令聲明的全局變量,不屬於全局對象的屬性。。還有就是引入module模塊的概念

31.你以爲jQueryzepto源碼有哪些寫的好的地方

(答案僅供參考)

jQuery源碼封裝在一個匿名函數的自執行環境中,有助於防止變量的全局污染,而後經過傳入window對象參數,能夠使window對象做爲局部變量使用,好處是當jQuery中訪問window對象的時候,就不用將做用域鏈退回到頂層做用域了,從而能夠更快的訪問window對象。一樣,傳入undefined參數,能夠縮短查找undefined時的做用域鏈。

(function( window, undefined ) {

         //用一個函數域包起來,就是所謂的沙箱

         //在這裏邊var定義的變量,屬於這個函數域內的局部變量,避免污染全局

         //把當前沙箱須要的外部變量經過函數參數引入進來

         //只要保證參數對內提供的接口的一致性,你還能夠隨意替換傳進來的這個參數

        window.jQuery = window.$ = jQuery;

  })( window );

jquery將一些原型屬性和方法封裝在了jquery.prototype中,爲了縮短名稱,又賦值給了jquery.fn,這是很形象的寫法。

有一些數組或對象的方法常常能使用到,jQuery將其保存爲局部變量以提升訪問速度。

jquery實現的鏈式調用能夠節約代碼,所返回的都是同一個對象,能夠提升代碼效率。

32.如何評價AngularJSBackboneJS

backbone具備依賴性,依賴underscore.jsBackbone + Underscore + jQuery(or Zepto) 就比一個AngularJS 多出了2 HTTP請求.

BackboneModel沒有與UI視圖數據綁定,而是須要在View中自行操做DOM來更新或讀取UI數據。AngularJS與此相反,Model直接與UI視圖綁定,ModelUI視圖的關係,經過directive封裝,angularjs內置的通用directive,就能實現大部分操做了,也就是說,基本沒必要關心ModelUI視圖的關係,直接操做Model就好了,UI視圖自動更新。

AngularJSdirective,你輸入特定數據,他就能輸出相應UI視圖。是一個比較完善的前端MVW框架,包含模板,數據雙向綁定,路由,模塊化,服務,依賴注入等全部功能,模板功能強大豐富,而且是聲明式的,自帶了豐富的 Angular 指令。

33.談談你對重構的理解

網站重構:在不改變外部行爲的前提下,簡化結構、添加可讀性,而在網站前端保持一致的行爲。也就是說是在不改變UI的狀況下,對網站進行優化, 
   
在擴展的同時保持一致的UI

對於傳統的網站來講重構一般是:
表格(table)佈局改成DIV+CSS
使網站前端兼容於現代瀏覽器(針對於不合規範的CSS、如對IE6有效的)
對於移動平臺的優化
針對於SEO進行優化
深層次的網站重構應該考慮的方面
減小代碼間的耦合
讓代碼保持彈性
嚴格按規範編寫代碼
設計可擴展的API
代替舊有的框架、語言(VB)
加強用戶體驗
一般來講對於速度的優化也包含在重構中
壓縮JSCSSimage等前端資源(一般是由服務器來解決)
程序的性能優化(如數據讀寫)
採用CDN來加速資源加載
對於JS DOM的優化
HTTP服務器的文件緩存

34.講講304緩存的原理

服務器首先產生ETag,服務器可在稍後使用它來判斷頁面是否已經被修改。本質上,客戶端經過將該記號傳回服務器要求服務器驗證其(客戶端)緩存。

304HTTP狀態碼,服務器用來標識這個文件沒修改,不返回內容,瀏覽器在接收到個狀態碼後,會使用瀏覽器已緩存的文件

客戶端請求一個頁面(A)。 服務器返回頁面A,並在給A加上一個ETag。 客戶端展示該頁面,並將頁面連同ETag一塊兒緩存。 客戶再次請求頁面A,並將上次請求時服務器返回的ETag一塊兒傳遞給服務器。 服務器檢查該ETag,並判斷出該頁面自上次客戶端請求以後還未被修改,直接返回響應304(未修改——Not Modified)和一個空的響應體。

: 動態主機配置協議,是一種讓系統得以鏈接到網絡上,並獲取所須要的配置參數手段。

35.什麼是 FOUC(無樣式內容閃爍)?你如何來避免 FOUC

FOUC - Flash Of Unstyled Content 文檔樣式閃爍

     <style type="text/css" media="all">@import "../fouc.css";</style>

    而引用CSS文件的@import就是形成這個問題的罪魁禍首。IE會先加載整個HTML文檔的DOM,而後再去導入外部的CSS文件,所以,在頁面DOM加載完成到CSS導入完成中間會有一段時間頁面上的內容是沒有樣式的,這段時間的長短跟網速,電腦速度都有關係。

 解決方法簡單的出奇,只要在<head>之間加入一個<link>或者<script>元素就能夠了。

36.說說你對Promise的理解

依照 Promise/A+ 的定義,Promise 有四種狀態:

pending: 初始狀態, fulfilled  rejected.
fulfilled: 成功的操做.
rejected: 失敗的操做.
settled: Promise已被fulfilledrejected,且不是pending

另外, fulfilled  rejected 一塊兒合稱 settled

Promise 對象用來進行延遲(deferred) 和異步(asynchronous ) 計算。

Promise對象有如下兩個特色:

1.  對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是承諾,表示其餘手段沒法改變。

2.  一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從Pending變爲Resolved和從Pending變爲Rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。

 

37.Promise 的構造函數

構造一個 Promise,最基本的用法以下:

var promise = new Promise(function(resolve, reject) {

        if (...) {  // succeed

            resolve(result);

        } else {   // fails

            reject(Error(errMessage));

        }

 });

Promise 實例擁有 then 方法(具備 then 方法的對象,一般被稱爲 thenable)。它的使用方法如: promise.then(onFulfilled, onRejected)

接收兩個函數做爲參數,一個在 fulfilled 的時候被調用,一個在 rejected 的時候被調用,接收參數就是 futureonFulfilled對應 resolveonRejected 對應 reject

38.說說mongoDBMySQL的區別

MySQL是傳統的關係型數據庫MongoDB則是非關係型數據庫

MongoDBBSON結構(二進制)進行存儲,對海量數據存儲有着很明顯的優點。

對比傳統關係型數據庫,NoSQL有着很是顯著的性能和擴展性優點,與關係型數據庫相比,mongodb的優勢有: 
  
①弱一致性(最終一致),更能保證用戶的訪問速度: 
  
②文檔結構的存儲方式,可以更便捷的獲取數據。

39.計算機網絡體系結構

應用層(HTTPSMTPFTPPOP3)

運輸層(TCPUDP)

網絡層(IP(路由器))

數據鏈路層(網橋(CSMA/CDPPP))

物理層(集線器)

40.說說網絡分層裏七層模型是哪七層

應用層:應用層、表示層、會話層(從上往下)(HTTPFTPSMTPDNS

傳輸層(TCPUDP

網絡層(IP

物理和數據鏈路層(以太網)

① 每一層的做用以下:

物理層:經過媒介傳輸比特,肯定機械及電氣規範(比特Bit

數據鏈路層:將比特組裝成幀和點到點的傳遞(幀Frame

網絡層:負責數據包從源到宿的傳遞和網際互連(包PackeT

傳輸層:提供端到端的可靠報文傳遞和錯誤恢復(段Segment

會話層:創建、管理和終止會話(會話協議數據單元SPDU

表示層:對數據進行翻譯、加密和壓縮(表示協議數據單元PPDU

應用層:容許訪問OSI環境的手段(應用協議數據單元APDU

  各類協議

ICMP協議: 因特網控制報文協議。它是TCP/IP協議族的一個子協議,用於在IP主機、路由器之間傳遞控制消息。 
    TFTP協議: 是TCP/IP協議族中的一個用來在客戶機與服務器之間進行簡單文件傳輸的協議,提供不復雜、開銷不大的文件傳輸服務。 
    HTTP協議: 超文本傳輸協議,是一個屬於應用層的面向對象的協議,因爲其簡捷、快速的方式,適用於分佈式超媒體信息系統。 
    DHCP協議: 動態主機配置協議,是一種讓系統得以鏈接到網絡上,並獲取所須要的配置參數手段。

41.說說TCP傳輸的三次握手四次揮手策略

爲了準確無誤地把數據送達目標處,TCP協議採用了三次握手策略。用TCP協議把數據包送出去後,TCP不會對傳送 後的狀況置之不理,它必定會向對方確認是否成功送達。握手過程當中使用了TCP的標誌:SYNACK

發送端首先發送一個帶SYN標誌的數據包給對方。接收端收到後,回傳一個帶有SYN/ACK標誌的數據包以示傳達確認信息。 
   
最後,發送端再回傳一個帶
ACK標誌的數據包,表明「握手」結束。 
   
若在握手過程當中某個階段莫名中斷,
TCP協議會再次以相同的順序發送相同的數據包。

42.斷開一個TCP鏈接則須要「四次握手」:

第一次揮手:主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不 會再給你發數據了(固然,在fin包以前發送出去的數據,若是沒有收到對應的ack  確認報文,主動關閉方依然會重發這些數據),可是,此時主動關閉方還可 以接受數據。

第二次揮手:被動關閉方收到FIN包後,發送一個ACK給對方,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號)。

第三次揮手:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,個人數據也發送完了,不會再給你發數據了。

第四次揮手:主動關閉方收到FIN後,發送一個ACK給被動關閉方,確認序號爲收到序號+1,至此,完成四次揮手。

43.TCPUDP的區別

TCPTransmission Control Protocol,傳輸控制協議)是基於鏈接的協議,也就是說,在正式收發數據前,必須和對方創建可靠的鏈接。一個TCP鏈接必需要通過三次「對話」才能創建起來

UDPUser Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是面向非鏈接的協議,它不與對方創建鏈接,而是直接就把數據包發送過去! 
   UDP
適用於一次只傳送少許數據、對可靠性要求不高的應用環境。

44.什麼叫優雅降級和漸進加強?
優雅降級:Web站點在全部新式瀏覽器中都能正常工做,若是用戶使用的是老式瀏覽器,則代碼會檢查以確認它們是否能正常工做。因爲IE獨特的盒模型佈局問題,針對不一樣版本的IEhack實踐過優雅降級了,爲那些沒法支持功能的瀏覽器增長候選方案,使之在舊式瀏覽器上以某種形式降級體驗卻不至於徹底失效.
漸進加強:從被全部瀏覽器支持的基本功能開始,逐步地添加那些只有新式瀏覽器才支持的功能,向頁面增長無害於基礎瀏覽器的額外樣式和功能的。當瀏覽器支持時,它們會自動地呈現出來併發揮做用。

漸進加強和優雅降級?

漸進加強 :針對低版本瀏覽器進行構建頁面,保證最基本的功能,而後再針對高級瀏覽器進行效果、交互等改進和追加功能達到更好的用戶體驗。

優雅降級 :一開始就構建完整的功能,而後再針對低版本瀏覽器進行兼容。

45.你以爲前端工程的價值體如今哪

爲簡化用戶使用提供技術支持(交互部分)
爲多個瀏覽器兼容性提供支持
爲提升用戶瀏覽速度(瀏覽器性能)提供支持
爲跨平臺或者其餘基於webkit或其餘渲染引擎的應用提供支持
爲展現數據提供支持(數據接口)

46.列舉IE 與其餘瀏覽器不同的特性?

IE支持currentStyleFIrefox使用getComputStyle

IE 使用innerTextFirefox使用textContent

濾鏡方面:IE:filter:alpha(opacity= num)Firefox-moz-opacity:num

事件方面:IEattachEvent:火狐是addEventListener

鼠標位置:IEevent.clientX;火狐是event.pageX

IE使用event.srcElementFirefox使用event.target

IE中消除list的原點僅需margin:0便可達到最終效果;FIrefox須要設置margin:0;padding:0以及list-style:none

CSS圓角:ie7如下不支持圓角

47.ie各版本和chrome能夠並行下載多少個資源

IE6 兩個併發,iE7升級以後的6個併發,以後版本也是6
Firefoxchrome也是6

48.FlashAjax各自的優缺點,在使用中如何取捨?
Flash
適合處理多媒體、矢量圖形、訪問機器;對CSS、處理文本上不足,不容易被搜索。
Ajax
CSS、文本支持很好,支持搜索;多媒體、矢量圖形、機器訪問不足。
共同點:與服務器的無刷新傳遞消息、用戶離線和在線狀態、操做DOM

49.說說你對前端架構師的理解

負責前端團隊的管理及與其餘團隊的協調工做,提高團隊成員能力和總體效率; 
帶領團隊完成研發工具及平臺前端部分的設計、研發和維護; 
帶領團隊進行前端領域前沿技術研究及新技術調研,保證團隊的技術領先 
負責前端開發規範制定、功能模塊化設計、公共組件搭建等工做,並組織培訓。

50.瞭解Node麼?Node的使用場景都有哪些?
    高併發、聊天、實時消息推送
51.介紹下你最經常使用的一款框架
    jquery,rn,angular
;
52.對於前端自動化構建工具備瞭解嗎?簡單介紹一下
    Gulp,Grunt
等;
53.說說最近最流行的一些東西吧?常去哪些網站?
   Node.js
MVVMReact-native,Angular,Weex
   CSDN,Segmentfault,
博客園,掘金,Stackoverflow,伯樂在線等
54.若是今年你打算熟練掌握一項新技術,那會是什麼?
   via
開發單頁webapp的技術。
   SAP
可以是頁面與頁面之間無縫鏈接,避免出現白頁,且帶有動態效果,提升用戶體驗。同時SAP,有JavaScript渲染頁面,而後在從服務器獲取小量的數據顯示,如此反覆,請求的數據無須要服務器處理,減小服務器負荷。
SAP
對技術要求高。要考慮首屏加載事件過長;動畫效果要考慮低端手機;垃圾收集,須要本身釋放資源,避免頁面變卡。
55.什麼樣的前端代碼是好的

高複用低耦合,這樣文件小,好維護,並且好擴展。

補充:

從輸入 URL 到頁面加載完成的過程當中都發生了什麼

1.  查找域名對應IP地址

這一步包括 DNS 具體的查找過程,包括:瀏覽器緩存->系統緩存->路由器緩存...
(1)
瀏覽器搜索本身的 DNS 緩存(維護一張域名與 IP 地址的對應表);
(2)
搜索操做系統中的 DNS 緩存(維護一張域名與 IP 地址的對應表);
(3)
搜索操做系統的 hosts 文件( Windows 環境下,維護一張域名與 IP 地址的對應表);
(4)
操做系統將域名發送至 LDNS(本地區域名服務器),LDNS 查詢 本身的 DNS 緩存(通常查找成功率    80% 左右),查找成功則返回結果,失敗則發起一個迭代 DNS 解析請求

LDNS Root Name Server (根域名服務器,如 comnetorg等的解析的頂級域名服務器的地址)發起請求,此處,Root Name Server 返回 com 域的頂級域名服務器的地址;

LDNS com 域的頂級域名服務器發起請求,返回 baidu.com 域名服務器地址; LDNS baidu.com 域名服務器發起請求,獲得 www.baidu.com IP 地址;

(5) LDNS 將獲得的 IP 地址返回給操做系統,同時本身也將 IP 地址緩存起來;

(6) 操做系統將 IP 地址返回給瀏覽器,同時本身也將 IP 地址緩存起來;

2. 創建鏈接(TCP的三次握手)

(1) 主機向服務器發送一個創建鏈接的請求;

(2) 服務器接到請求後發送贊成鏈接的信號;

(3) 主機接到贊成鏈接的信號後,再次向服務器發送了確認信號 ;

注意:這裏的三次握手中主機兩次向服務器發送確認,第二次是爲了防止已失效的鏈接請求報文段傳至服務器致使錯誤。

3.構建網頁

(1) 瀏覽器根據 URL 內容生成 HTTP 請求,請求中包含請求文件的位置、請求文件的方式等等;

(2) 服務器接到請求後,會根據 HTTP 請求中的內容來決定如何獲取相應的 HTML 文件;

(3) 服務器將獲得的 HTML 文件發送給瀏覽器;

(4) 在瀏覽器尚未徹底接收 HTML 文件時便開始渲染、顯示網頁;

(5) 在執行 HTML 中代碼時,根據須要,瀏覽器會繼續請求圖片、音頻、視頻、CSSJS等文件,過程同請求 HTML

瀏覽器渲染展現網頁過程

1.  HTML代碼轉化爲DOM(DOM Tree)

2.  CSS代碼轉化成CSSOMCSS Object Model

3.  結合DOMCSSOM,生成一棵渲染樹(包含每一個節點的視覺信息)(Render Tree)

4.  生成佈局(layout),即將全部渲染樹的全部節點進行平面合成

5.  將佈局繪製(paint)在屏幕上

4. 斷開鏈接(TCP的四次揮手)

(1) 主機向服務器發送一個斷開鏈接的請求;

(2) 服務器接到請求後發送確認收到請求的信號;(此時服務器可能還有數據要發送至主機)

(3) 服務器向主機發送斷開通知(此時服務器確認沒有要向主機發送的數據)

(4) 主機接到斷開通知後斷開鏈接並反饋一個確認信號,服務器收到確認信號後斷開鏈接;

注意:這裏的四次揮手中服務器兩次向主機發送消息,第一次是回覆主機已收到斷開的請求,第二次是向主機確認是否斷開,確保數據傳輸完畢。

插件:

1有了解過React.js嗎?

React.js 只是一個視圖庫

    1)聲明式設計

    2)高效:經過對DOM的模擬,最大限度的減小與DOM的交互。

    3)靈活:能夠與已知的框架或庫很好的配合。

    4JSX:是js語法的擴展,不必定使用,但建議用。

    (5)組件:構建組件,使代碼更容易獲得複用,可以很好地應用在大項目的開發中。

    (6)單向響應的數據流:React實現了單向響應的數據流,從而減小了重複代碼,這也是解釋了它爲何比傳統數據綁定更簡單。

2. angularvue的區別

1.vue僅僅是mvvm中的view層,只是一個如jquery般的工具庫,而不是框架,而angular而是mvvm框架。

2.vue的雙向邦定是基於ES5 中的 getter/setter來實現的,而angular而是由本身實現一套模版編譯規則,須要進行所謂的「髒」檢查,vue則不須要。所以,vue在性能上更高效,可是代價是對於ie9如下的瀏覽器沒法支持。

3.vue須要提供一個el對象進行實例化,後續的全部做用範圍也是在el對象之下,而angular而是整個html頁面。一個頁面,能夠有多個vue實例,而angular好像不是這麼玩的。

4.vue真的很容易上手,學習成本相對低,不過能夠參考的資料不是很豐富,官方文檔比較簡單,缺乏全面的使用案例。高級的用法,須要本身去研究源碼,至少目前是這樣。

3.less的特色

每次被問到這個我只能想起less中的定義變量,用過久less都忘了css不能嵌套,醉了醉了。

1.  變量

2.  混合(Mixins

3.  嵌套規則

4.  運算

5.  函數

6.  命名空間

7.  做用域

8.  註釋

9.  導入(Import

4.less的原理

本質上,less 包含一套自定義的語法及一個解析器,用戶根據這些語法定義本身的樣式規則,這些規則最終會經過解析器,less 把這些樣式規則編譯成瀏覽器能夠識別的 css 樣式。less 並無裁剪 css 原有的特性,更不是用來取代 css 的,而是在現有 css 語法的基礎上,爲 css 加入程序式語言的特性。less 最終須要編譯成 css 文件才能起到樣式的效果,咱們能夠稱 less css 樣式生成工具。

5. gulp的特色

1.  使用 gulp.js,你的構建腳本是代碼,而不是配置文件;

2.  使用標準庫(node.js standard library)來編寫腳本;

3.  插件都很簡單,只負責完成一件事-基本上都是 20 行左右的函數;

4.  任務都以最大的併發數來執行;

5.  Gulp是一個基於流的構建系統,使用代碼優於配置的策略。輸入/輸出(I/O)是基於流式的。

做用:

1.  SassLess編譯

2.  Css Js 圖片壓縮

3.  Css Js 合併

4.  Css Js 內聯

5.  Htmlinclude功能

6.  Autoprefixer(自動處理瀏覽器css前綴)

7.  自動刷新

8.  去緩存

9.  Handlebars模板文件的預編譯

10. 雪碧圖

11. ESLint

12. rem移動端適配方案

6.Promise對象有如下兩個特色。

1.  對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是承諾,表示其餘手段沒法改變。

2.  一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從Pending變爲Resolved和從Pending變爲Rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。

7.js的冒泡(Bubbling Event)和捕獲(Capture Event)的區別

js之事件冒泡和事件捕獲詳細介紹

1.  冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發。

2.  捕獲型事件(event capturing):事件從最不精確的對象(document 對象)開始觸發,而後到最精確(也能夠在窗口級別捕獲事件,不過必須由開發人員特別指定)

3.  DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件,可是,捕獲型事件先發生。兩種事件流會觸及DOM中的全部對象,從document對象開始,也在document對象結束。

 
 
 
 
 
 
 
 (IE中不會)4.  DOM事件模型最獨特的性質是,文本節點也觸發事件

示例
假設一個元素div,它有一個下級元素p

<div>
<p></p>            元素
</div>

這兩個元素都綁定了click事件,若是用戶點擊了p

     1.事件捕獲

div當你使用事件捕獲時,**父級元素先觸發**,子級元素後觸發,即先觸發,p後觸發。

     2.事件冒泡

div     3.當你使用事件冒泡時,**子級元素先觸發**,父級元素後觸發,即p先觸發,後觸發。

addEventListener函數,它有三個參數,第三個參數如果true,則表示採用事件捕獲,如果false,則表示採用事件冒泡。
      IE
只支持事件冒泡,不支持事件捕獲。

8.svngit的區別

  1. git是分佈式的,svn不是。

2.  gitsvn同樣有本身的集中式版本庫或服務器。但git更傾向於被使用於分佈式模式,克隆版本庫後即便沒有網絡也可以commit文件,查看歷史版本記錄,建立項目分支等,等網絡再次鏈接上Push到服務器端。

  1. git把內容按元數據方式存儲,而svn是按文件。

4.  全部的資源控制系統都是把文件的元信息隱藏在一個相似.svn,.cvs等的文件夾裏。

5.  git目錄是處於你的機器上的一個克隆版的版本庫,它擁有中心版本庫上全部的東西,例如標籤,分支,版本記錄等。

  1. git沒有一個全局的版本號,svn有。
  2. git的內容完整性優於svn

8.  由於git的內容存儲使用的是SHA-1哈希算法。

  1. git能夠有無限個版本庫,svn只能有一個指定中央版本庫。

10. svn中央版本庫有問題時,全部工做成員都一塊兒癱瘓直到版本庫維修完畢或者新的版本庫設立完成。

11. 每個git都是一個版本庫,區別是它們是否擁有活躍目錄(Git Working Tree)。若是主要版本庫(例如:置於GitHub的版本庫)有問題,工做成員仍然能夠在本身的本地版本庫(local repository)提交,等待主要版本庫恢復便可。工做成員也能夠提交到其餘的版本庫!


9對前端工程師這個職位你是怎麼樣理解的?

a. 前端是最貼近用戶的程序員,前端的能力就是能讓產品從 90分進化到 100 分,甚至更好

b. 參與項目,快速高質量完成實現效果圖,精確到1px

c. 與團隊成員,UI設計,產品經理的溝通;

d. 作好的頁面結構,頁面重構和用戶體驗;

e. 處理hack,兼容、寫出優美的代碼格式;

f. 針對服務器的優化、擁抱最新前端技術。

 

 

 

 

擴展:

1.自我介紹:除了基本我的信息之外,面試官更想聽的是你不同凡響的地方和你的優點。
2.項目介紹
3.如何看待前端開發?
4.平時是如何學習前端開發的?
5.將來三到五年的規劃是怎樣的?

算法部分:

1.編寫一個方法 求一個字符串的字節長度

假設:一個英文字符佔用一個字節,一箇中文字符佔用兩個字節

function GetBytes(str){ var len = str.length; var bytes = len; for(var i=0; i<len; i++){ if (str.charCodeAt(i) > 255) bytes++; } return bytes; } alert(GetBytes("你好,as"));

2.統計一個字符串出現最多的字母

給出一段英文連續的英文字符竄,找出重複出現次數最多的字母

    輸入 afjghdfraaaasdenas

    輸出 a
前面出現過去重的算法,這裏須要是統計重複次數。
function findMaxDuplicateChar(str) { if(str.length == 1) { return str; } let charObj = {}; for(let i=0;i<str.length;i++) { if(!charObj[str.charAt(i)]) { charObj[str.charAt(i)] = 1; }else{ charObj[str.charAt(i)] += 1; } } let maxChar = '', maxValue = 1; for(var k in charObj) { if(charObj[k] >= maxValue) { maxChar = k; maxValue = charObj[k]; } } return maxChar; } module.exports = findMaxDuplicateChar;

 

統計字符串中字母個數或統計最多字母數

 

var str = "aaaabbbccccddfgh";
var obj  = {};
for(var i=0;i<str.length;i++){
    var v = str.charAt(i);
    if(obj[v] && obj[v].value == v){
        obj[v].count = ++ obj[v].count;
    }else{
        obj[v] = {};
        obj[v].count = 1;
        obj[v].value = v;
    }
}
for(key in obj){
    document.write(obj[key].value +'='+obj[key].count+'&nbsp;'); // a=4  b=3  c=4  d=2  f=1  g=1  h=1 
}

 

 

 

3.JS數組去重

如下是展現三種方法

Array.prototype.unique1 = function () { var n = []; //一個新的臨時數組
  for (var i = 0; i < this.length; i++) //遍歷當前數組
 { //若是當前數組的第i已經保存進了臨時數組,那麼跳過,
    //不然把當前項push到臨時數組裏面
    if (n.indexOf(this[i]) == -1) n.push(this[i]); } return n; } Array.prototype.unique2 = function() { var n = {},r=[]; //n爲hash表,r爲臨時數組
    for(var i = 0; i < this.length; i++) //遍歷當前數組
 { if (!n[this[i]]) //若是hash表中沒有當前項
 { n[this[i]] = true; //存入hash表
            r.push(this[i]); //把當前數組的當前項push到臨時數組裏面
 } } return r; } Array.prototype.unique3 = function() { var n = [this[0]]; //結果數組
    for(var i = 1; i < this.length; i++) //從第二項開始遍歷
 { //若是當前數組的第i項在當前數組中第一次出現的位置不是i,
        //那麼表示第i項是重複的,忽略掉。不然存入結果數組
        if (this.indexOf(this[i]) == i) n.push(this[i]); } return n; }

4.去掉一組整型數組重複的值

 好比輸入: [1,13,24,11,11,14,1,2]

 輸出: [1,13,24,11,14,2]
 須要去掉重複的11 1 這兩個元素。
這道問題出如今諸多的前端面試題中,主要考察我的對Object的使用,利用key來進行篩選。
/** * unique an array **/ let unique = function(arr) { let hashTable = {}; let data = []; for(let i=0,l=arr.length;i<l;i++) { if(!hashTable[arr[i]]) { hashTable[arr[i]] = true; data.push(arr[i]); } } return data } module.exports = unique;

5.js操做獲取和設置cookie

//建立cookie
function setCookie(name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value); if (expires instanceof Date) { cookieText += '; expires=' + expires; } if (path) { cookieText += '; expires=' + expires; } if (domain) { cookieText += '; domain=' + domain; } if (secure) { cookieText += '; secure'; } document.cookie = cookieText; } //獲取cookie
function getCookie(name) { var cookieName = encodeURIComponent(name) + '='; var cookieStart = document.cookie.indexOf(cookieName); var cookieValue = null; if (cookieStart > -1) { var cookieEnd = document.cookie.indexOf(';', cookieStart); if (cookieEnd == -1) { cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)); } return cookieValue; } //刪除cookie
function unsetCookie(name) { document.cookie = name + "= ; expires=" + new Date(0); }

 6.編寫一個b繼承a的方法

function A(name){ this.name = name; this.sayHello = function(){alert(this.name+」 say Hello!」);}; } function B(name,id){ this.temp = A; this.temp(name);        //至關於new A();
    delete this.temp; this.id = id; this.checkId = function(ID){alert(this.id==ID)}; }

7.如何阻止事件冒泡和默認事件

function stopBubble(e) { if (e && e.stopPropagation) e.stopPropagation() else window.event.cancelBubble=true } return false

8.下面程序執行後彈出什麼樣的結果?

function fn() { this.a = 0; this.b = function() { alert(this.a) } } fn.prototype = { b: function() { this.a = 20; alert(this.a); }, c: function() { this.a = 30; alert(this.a); } } var myfn = new fn(); myfn.b(); myfn.c();

 

9.下面程序的結果

function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3); var b = fun(0).fun(1).fun(2).fun(3); var c = fun(0).fun(1);  c.fun(2);  c.fun(3); //答案:

//a: undefined,0,0,0 //b: undefined,0,1,2 //c: undefined,0,1,1

10.下面程序的輸出結果

var name = 'World!'; (function () { if (typeof name === 'undefined') { var name = 'Jack'; console.log('Goodbye ' + name); } else { console.log('Hello ' + name); } })(); //Goodbye Jack

11.快速 排序的思想並實現一個快排?

  「快速排序」的思想很簡單,整個排序過程只須要三步:

  (1)在數據集之中,找一個基準點

  (2)創建兩個數組,分別存儲左邊和右邊的數組

  (3)利用遞歸進行下次比較

<script type="text/javascript">

        function quickSort(arr){ if(arr.length<=1){ return arr;//若是數組只有一個數,就直接返回;
 } var num = Math.floor(arr.length/2);//找到中間數的索引值,若是是浮點數,則向下取整

            var numValue = arr.splice(num,1);//找到中間數的值
            var left = []; var right = []; for(var i=0;i<arr.length;i++){ if(arr[i]<numValue){ left.push(arr[i]);//基準點的左邊的數傳到左邊數組
 } else{ right.push(arr[i]);//基準點的右邊的數傳到右邊數組
 } } return quickSort(left).concat([numValue],quickSort(right));//遞歸不斷重複比較
 } alert(quickSort([32,45,37,16,2,87]));//彈出「2,16,32,37,45,87」
 </script>

 

手寫數組快速排序:

關於快排算法的詳細說明,能夠參考阮一峯老師的文章快速排序
"快速排序"的思想很簡單,整個排序過程只須要三步:
(1)在數據集之中,選擇一個元素做爲"基準"(pivot)。
(2)全部小於"基準"的元素,都移到"基準"的左邊;全部大於"基準"的元素,都移到"基準"的右邊。
(3)對"基準"左邊和右邊的兩個子集,不斷重複第一步和第二步,直到全部子集只剩下一個元素爲止。
參考代碼:

var quickSort = function(arr) {
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat([pivot], quickSort(right));
};

 

 

12.實現一個函數clone,能夠對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值複製

第一種(好用):

 

function clone(obj) {
    var o;
    switch (typeof obj) {
        case "undefined":
            break;
        case "string":
            o = obj + "";
            break;
        case "number":
            o = obj - 0;
            break;
        case "boolean":
            o = obj;
            break;
        case "object": // object 分爲兩種狀況 對象(Object)或數組(Array)
            if (obj === null) {
                o = null;
            } else {
                if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") {
                    o = [];
                    for (var i = 0; i < obj.length; i++) {
                        o.push(clone(obj[i]));
                    }
                } else {
                    o = {};
                    for (var k in obj) {
                        o[k] = clone(obj[k]);
                    }
                }
            }
            break;
        default:
            o = obj;
            break;
    }
    return o;
}
View Code

 

 

 

第二種:

Object.prototype.clone = function(){ var o = this.constructor === Array ? [] : {}; for(var e in this){ o[e] = typeof this[e] === "object" ? this[e].clone() : this[e]; } return o; }

 13.如何獲取UA?

function whatBrowser() { document.Browser.Name.value=navigator.appName; document.Browser.Version.value=navigator.appVersion; document.Browser.Code.value=navigator.appCodeName; document.Browser.Agent.value=navigator.userAgent; } 

14.常規GruntFile.js && gulpFile.js

①.GruntFile.js

<script> module.exports = function(grunt) { // 導入模塊
        grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-htmlmin'); grunt.loadNpmTasks('grunt-contrib-imagemin'); grunt.loadNpmTasks('grunt-contrib-watch'); // 配置任務
 grunt.initConfig({ // js壓縮 默認加密壓縮
            uglify: { // 主任務名稱
                options: { // [配置選項]
                    mangle: false // 是否加密壓縮
 }, a: { // 子任務名稱
                    expand: true, // 是否分開壓縮
                    src: 'js/*.js',    // 源文件
                    dest: 'build'    // 目標文件 自動建立源文件文件夾
 } }, cssmin: { a: { expand: true, src: 'css/*.css', dest: 'build' } }, htmlmin: { options: { removeComments: true,    // 是否移除註釋
                    collapseWhitespace: false    // 是否去掉空白
 }, a: { src: '*.html', dest: 'build' } }, // imagemin: {
            // a: {
            // expand: true, //分開執行
            // cwd: 'images',
            // src: ['**/*.{png,jpg}'],
            // dest: 'build/images'
            // }
            // },
 watch: { a: { files: ['*.html', 'css/*.css', 'js/*.js'], tasks: ['cssmin', 'htmlmin', 'uglify'] } } }); // 註冊一個默認任務
        grunt.registerTask('default', ['uglify', 'cssmin', 'htmlmin', 'watch']); } </script>

②.gulpfile.js

<script>
    // 導入模塊
    var gulp = require('gulp'); var cssmin = require('gulp-cssmin'); var uglify = require('gulp-uglify'); var htmlmin = require('gulp-htmlmin'); var concat = require('gulp-concat'); var rename = require('gulp-rename');    // 更名

    // 配置任務
    gulp.task('uglify:css', function() { gulp.src('css/*.css') .pipe(cssmin()) // 壓縮
            .pipe(concat('all.min.css'))    // 合併
            .pipe(gulp.dest('build/css'))    // 輸出
 }); gulp.task('uglify:js', function() { gulp.src('js/*.js') .pipe(uglify()) // 壓縮
            .pipe(gulp.dest('build/js'))    // 輸出
 }); gulp.task('uglify:html', function() { gulp.src('*.html') .pipe(htmlmin({ // 壓縮
                collapseWhitespace: true, removeComments: true })) .pipe(gulp.dest('build'))        // 輸出
 }); gulp.watch('*.*', ['uglify:css', 'uglify:js', 'uglify:html']); gulp.task('default', ['uglify:css', 'uglify:js', 'uglify:html']); </script>
<script>
    var gulp = require('gulp'); var uglify = require('gulp-uglify'); var clean = require('gulp-clean-css'); var sass = require('gulp-sass'); gulp.task('uglify',function(){ return( gulp.src('./src/*.js') .pipe(uglify()) .pipe(gulp.dest('dist')) ) }) gulp.task('minify-css',function(){ return ( gulp.src('./src/*.css') .pipe(clean()) .pipe(gulp.dest('dist')) ) }) gulp.task('compile-sass',function(){ return ( gulp.src('./src/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('dist')) ) }) gulp.task('default',function(){ gulp.watch('./src/*.js',['uglify']); gulp.watch('./src/*.css',['minify-css']); gulp.watch('./src/*.scss',['compile-sass']); }) </script>

15.ajax過程 

  1. 得到ajax

  2. 打開地址

  3. 發送數據

  4. 接收數據

<script>
 // 1.得到ajax
 if (window.XMLHttpRequest) { //查看當前瀏覽器XMLHttpRequest是不是全局變量
     var oAjax = new XMLHttpResquest(); } else { var oAjax = new ActiveXObject('Microsoft.XMLHTTP'); //IE6,傳入微軟參數
 } // 2.打開地址
 switch (json.type.toLowerCase()) { case 'get': oAjax.open('GET', json.url + '?' + jsonToURL(json.data), true); // 提交方式(大寫),url,是否異步
         oAjax.send(); // 3.發送數據
         break; case 'post': oAjax.open('POST', json.url, true); oAjax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); oAjax.send(jsonToURL(json.data)); // 3.發送數據
         break; } // 4.接收數據
 oAjax.onreadystatechange = function() { //監控狀態
     if (oAjax.readyState == 4) { json.complete && json.complete(); if (oAjax.status >= 200 && oAjax.status < 300 || oAjax.status == 304) { json.success && json.success(oAjax.responseText); //執行成功的回調函數, responseText爲響應內容
         } else { json.error && json.error(oAjax.status); //執行失敗的回調函數
 } } }; </script>

16.less不依靠構建轉css

甩上gulp構建轉化

<script>
    var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function() { gulp.src(['src/less/index.less', 'src/less/detail.less']) //多個文件以數組形式傳入
 .pipe(less()) .pipe(gulp.dest('src/css')); //將會在src/css下生成index.css以及detail.css 
 }); gulp.task('testWatch', function() { gulp.watch('src/**/*.less', ['testLess']); //當全部less文件發生改變時,調用testLess任務
 }); </script>

1七、冒泡、快排

①、冒泡排序

每次比較相鄰的兩個數,若是後一個比前一個小,換位置。 時間複雜度:O(n^2)
<script>
    var arr = [3, 1, 4, 6, 5, 7, 2]; function bubbleSort(arr) { var len = arr.length; for (var i = len; i >= 2; --i) { for (var j = 0; j < i - 1; j++) { if (arr[j + 1] < arr[j]) { var temp; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } function bubbleSort2(arr) { var len = arr.length; for (var i = 0; i <= len - 1; i++) { for (var j = 0; j <= len - i; j++) { if (arr[j + 1] < arr[j]) { var temp; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } console.log(bubbleSort(arr)); console.log(bubbleSort2(arr)); </script>

②、快速排序

採用二分法,取出中間數,數組每次和中間數比較,小的放到左邊,大的放到右邊。 時間複雜度:O(nlog2(n))
<script>
    var arr = [3, 1, 4, 6, 5, 7, 2]; function quickSort(arr) { if(arr.length == 0) { return [];    // 返回空數組
 } var cIndex = Math.floor(arr.length / 2); var c = arr.splice(cIndex, 1); var l = []; var r = []; for (var i = 0; i < arr.length; i++) { if(arr[i] < c) { l.push(arr[i]); } else { r.push(arr[i]); } } return quickSort(l).concat(c, quickSort(r)); } console.log(quickSort(arr)); </script>

18.數組的翻轉(非reverse)

<script>
    var arr=[1,2,3,4]; var arr2=[]; while(arr.length) { var num=arr.pop(); arr2.push(num); } alert(arr2); </script>

19.判斷一個單詞是不是迴文?

迴文是指把相同的詞彙或句子,在下文中調換位置或顛倒過來,產生首尾迴環的情趣,叫作迴文,也叫回環。好比 mamam redivider .

不少人拿到這樣的題目很是容易想到用for 將字符串顛倒字母順序而後匹配就好了。其實重要的考察的就是對於reverse的實現。其實咱們能夠利用現成的函數,將字符串轉換成數組,這個思路很重要,咱們能夠擁有更多的自由度去進行字符串的一些操做。

function checkPalindrom(str) { return str == str.split('').reverse().join(''); }

 

 

20.排序算法

若是抽到算法題目的話,應該大多都是比較開放的題目,不限定算法的實現,可是必定要求掌握其中的幾種,因此冒泡排序,這種較爲基礎而且便於理解記憶的算法必定須要熟記於心。冒泡排序算法就是依次比較大小,小的的大的進行位置上的交換。

function bubbleSort(arr) { for(let i = 0,l=arr.length;i<l-1;i++) { for(let j = i+1;j<l;j++) { if(arr[i]>arr[j]) { let tem = arr[i]; arr[i] = arr[j]; arr[j] = tem; } } } return arr; } module.exports = bubbleSort;

21.不借助臨時變量,進行兩個整數的交換

   輸入 a = 2, b = 4 輸出 a = 4, b =2

 

這種問題很是巧妙,須要你們跳出慣有的思惟,利用 a , b進行置換。

主要是利用 + – 去進行運算,相似 a = a + ( b – a) 實際上等同於最後 的 a = b;

function swap(a , b) { b = b - a; a = a + b; b = a - b; return [a,b]; } module.exports = swap;

22.使用canvas 繪製一個有限度的斐波那契數列的曲線?

 

 數列長度限定在9

斐波那契數列,又稱黃金分割數列,指的是這樣一個數列:0、一、一、二、三、五、八、1三、2一、3四、……在數學上,斐波納契數列主要考察遞歸的調用。咱們通常都知道定義

      fibo[i] = fibo[i-1]+fibo[i-2];

生成斐波那契數組的方法

function getFibonacci(n) { var fibarr = []; var i = 0; while(i<n) { if(i<=1) { fibarr.push(i); }else{ fibarr.push(fibarr[i-1] + fibarr[i-2]) } i++; } return fibarr; }

剩餘的工做就是利用canvas arc方法進行曲線繪製了

 html

<canvas></canvas>

css

canvas{ width: 600px; height:480px; background: #000;
  }

js

var canvas = document.querySelector('canvas'); canvas.width = 600; canvas.height = 480; var coor = { x: 300, y: 240, }; var ctx = canvas.getContext('2d'); function draw(r, n ,prevR) { if(n>2) { switch(n%4) { case 0 : coor.y = coor.y - 5 * prevR; coor.y = coor.y + 5 * r; break; case 1 : coor.x = coor.x + 5 * prevR; coor.x = coor.x - 5 * r; break; case 2 : coor.y = coor.y + 5 * prevR; coor.y = coor.y - 5 * r; break; case 3 : coor.x = coor.x - 5 * prevR; coor.x = coor.x + 5 * r; break; } } ctx.beginPath(); ctx.arc(coor.x,coor.y,5*r,Math.PI*0.5*(n),Math.PI*0.5*(n-1),true); if(n>1) { switch(n%4) { case 0 : ctx.moveTo(coor.x - 5*r,coor.y); break; case 1 : ctx.moveTo(coor.x,coor.y + 5*r); break; case 2 : ctx.moveTo(coor.x + 5*r,coor.y); break; case 3 : ctx.moveTo(coor.x,coor.y-5*r); break; } } ctx.lineWidth = 1; ctx.strokeStyle = '#fff'; ctx.stroke(); } function getFibonacci(n) { var fibarr = []; var i = 0; while(i<n) { if(i<=1) { fibarr.push(i); }else{ fibarr.push(fibarr[i-1] + fibarr[i-2]) } i++; } return fibarr; } var data = getFibonacci(10); for(var i = 0,l=data.length;i<l;i++) { if(data[i]!=0) { draw(data[i],i,data[i-1]); } }

23.找出下列正數組的最大差值好比:

     輸入 [10,5,11,7,8,9]

     輸出 6

 這是經過一道題目去測試對於基本的數組的最大值的查找,很明顯咱們知道,最大差值確定是一個數組中最大值與最小值的差。

 

 function getMaxProfit(arr) { var minPrice = arr[0]; var maxProfit = 0; for (var i = 0; i < arr.length; i++) { var currentPrice = arr[i]; minPrice = Math.min(minPrice, currentPrice); var potentialProfit = currentPrice - minPrice; maxProfit = Math.max(maxProfit, potentialProfit); } return maxProfit; }

24.隨機生成指定長度的字符串:

實現一個算法,隨機生成指制定長度的字符竄。

    好比給定 長度 8  輸出 4ldkfg9j

 

function randomString(n) { let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; let tmp = '', i = 0, l = str.length; for (i = 0; i < n; i++) { tmp += str.charAt(Math.floor(Math.random() * l)); } return tmp; } module.exports = randomString;

25.實現相似getElementsByClassName 的功能

本身實現一個函數,查找某個DOM節點下面的包含某個class的全部DOM節點?不容許使用原生提供的 getElementsByClassName querySelectorAll 等原生提供DOM查找函數。


function queryClassName(node, name) { var starts = '(^|[ \n\r\t\f])', ends = '([ \n\r\t\f]|$)'; var array = [], regex = new RegExp(starts + name + ends), elements = node.getElementsByTagName("*"), length = elements.length, i = 0, element; while (i < length) { element = elements[i]; if (regex.test(element.className)) { array.push(element); } i += 1; } return array; }

 26.使用JS 實現二叉查找樹(Binary Search Tree)

通常叫所有寫完的機率比較少,可是重點考察你對它的理解和一些基本特色的實現。 二叉查找樹,也稱二叉搜索樹、有序二叉樹(英語:ordered binary tree)是指一棵空樹或者具備下列性質的二叉樹:

  • 任意節點的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值;
  • 任意節點的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值;
  • 任意節點的左、右子樹也分別爲二叉查找樹;
  • 沒有鍵值相等的節點。二叉查找樹相比於其餘數據結構的優點在於查找、插入的時間複雜度較低。爲O(log n)。二叉查找樹是基礎性數據結構,用於構建更爲抽象的數據結構,如集合、multiset、關聯數組等。

 

在寫的時候須要足夠理解二叉搜素樹的特色,須要先設定好每一個節點的數據結構

class Node { constructor(data, left, right) { this.data = data; this.left = left; this.right = right; } }

樹是有節點構成,由根節點逐漸延生到各個子節點,所以它具有基本的結構就是具有一個根節點,具有添加,查找和刪除節點的方法.

class BinarySearchTree { constructor() { this.root = null; } insert(data) { let n = new Node(data, null, null); if (!this.root) { return this.root = n; } let currentNode = this.root; let parent = null; while (1) { parent = currentNode; if (data < currentNode.data) { currentNode = currentNode.left; if (currentNode === null) { parent.left = n; break; } } else { currentNode = currentNode.right; if (currentNode === null) { parent.right = n; break; } } } } remove(data) { this.root = this.removeNode(this.root, data) } removeNode(node, data) { if (node == null) { return null; } if (data == node.data) { // no children node
      if (node.left == null && node.right == null) { return null; } if (node.left == null) { return node.right; } if (node.right == null) { return node.left; } let getSmallest = function(node) { if(node.left === null && node.right == null) { return node; } if(node.left != null) { return node.left; } if(node.right !== null) { return getSmallest(node.right); } } let temNode = getSmallest(node.right); node.data = temNode.data; node.right = this.removeNode(temNode.right,temNode.data); return node; } else if (data < node.data) { node.left = this.removeNode(node.left,data); return node; } else { node.right = this.removeNode(node.right,data); return node; } } find(data) { var current = this.root; while (current != null) { if (data == current.data) { break; } if (data < current.data) { current = current.left; } else { current = current.right } } return current.data; } } module.exports = BinarySearchTree;

27.實現一個函數clone,能夠對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值複製。

 /**
 * 對象克隆
 * 支持基本數據類型及對象
 * 遞歸方法
 */
function clone(obj) {
    var o;
    switch (typeof obj) {
        case "undefined":
            break;
        case "string":
            o = obj + "";
            break;
        case "number":
            o = obj - 0;
            break;
        case "boolean":
            o = obj;
            break;
        case "object": // object 分爲兩種狀況 對象(Object)或數組(Array)
            if (obj === null) {
                o = null;
            } else {
                if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") {
                    o = [];
                    for (var i = 0; i < obj.length; i++) {
                        o.push(clone(obj[i]));
                    }
                } else {
                    o = {};
                    for (var k in obj) {
                        o[k] = clone(obj[k]);
                    }
                }
            }
            break;
        default:
            o = obj;
            break;
    }
    return o;
}

28.如何消除一個數組裏面重復的元素?

// 方法一:
var arr1 =[1,2,2,2,3,3,3,4,5,6],
    arr2 = [];
for(var i = 0,len = arr1.length; i< len; i++){
    if(arr2.indexOf(arr1[i]) < 0){
        arr2.push(arr1[i]);
    }
}
document.write(arr2); // 1,2,3,4,5,6

 

29.在Javascript中什麼是僞數組?如何將僞數組轉化爲標準數組?

僞數組(類數組):沒法直接調用數組方法或指望length屬性有什麼特殊的行爲,但仍能夠對真正數組遍歷方法來遍歷它們。典型的是函數的argument參數,還有像調用getElementsByTagName,document.childNodes之類的,它們都返回NodeList對象都屬於僞數組。能夠使用Array.prototype.slice.call(fakeArray)將數組轉化爲真正的Array對象。

function log(){
      var args = Array.prototype.slice.call(arguments);  
//爲了使用unshift數組方法,將argument轉化爲真正的數組
      args.unshift('(app)');
 
      console.log.apply(console, args);
};

30.JavaScript實現二分法查找

二分法查找,也稱折半查找,是一種在有序數組中查找特定元素的搜索算法。查找過程能夠分爲如下步驟:
(1)首先,從有序數組的中間的元素開始搜索,若是該元素正好是目標元素(即要查找的元素),則搜索過程結束,不然進行下一步。
(2)若是目標元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半區域查找,而後重複第一步的操做。
(3)若是某一步數組爲空,則表示找不到目標元素。
參考代碼:

// 非遞歸算法
        function binary_search(arr, key) {
            var low = 0,
                high = arr.length - 1;
            while(low <= high){
                var mid = parseInt((high + low) / 2);
                if(key == arr[mid]){
                    return  mid;
                }else if(key > arr[mid]){
                    low = mid + 1;
                }else if(key < arr[mid]){
                    high = mid -1;
                }else{
                    return -1;
                }
            }
        };
        var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];
        var result = binary_search(arr,10);
        alert(result); // 9 返回目標元素的索引值       
// 遞歸算法
        function binary_search(arr,low, high, key) {
            if (low > high){
                return -1;
            }
            var mid = parseInt((high + low) / 2);
            if(arr[mid] == key){
                return mid;
            }else if (arr[mid] > key){
                high = mid - 1;
                return binary_search(arr, low, high, key);
            }else if (arr[mid] < key){
                low = mid + 1;
                return binary_search(arr, low, high, key);
            }
        };
        var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];
        var result = binary_search(arr, 0, 13, 10);
        alert(result); // 9 返回目標元素的索引值  

31.寫一個function,清除字符串先後的空格。(兼容全部瀏覽器)

function trim(str) {
    if (str && typeof str === "string") {
        return str.replace(/(^\s*)|(\s*)$/g,""); //去除先後空白符
    }
}

32.使用正則表達式驗證郵箱格式

 var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
    var email = "example@qq.com";
    console.log(reg.test(email));  // true  

 

 

參考:

http://web.jobbole.com/88471/

http://www.javashuo.com/article/p-bvqfhhls-bx.html

http://blog.csdn.net/kebi007/article/details/54882425#t4

http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html

http://www.cnblogs.com/GeniusLyzh/p/5272902.html

相關文章
相關標籤/搜索