面試題整理

 

html

什麼是語義化的HTML?javascript

  1. 選擇合適的標籤。搜索引擎的爬蟲也依賴於標記來肯定上下文和各個關鍵字的權重。這對搜索引擎的抓取有好處。
  2. 符合內容的結構化:在沒有CSS的狀況下,讓頁面展示出清晰地結構。
  3. 有利於開發和維護:可以使閱讀源代碼的人更容易明白網頁的結構。

說下行內元素和塊級元素的區別?行內塊元素的兼容性使用?(IE8 如下)php

行內元素特性:css

  1. 和相鄰的內聯元素在同一行
  2. 寬度、高度,padding-top/bottom、margin-top/bottom都不可設置

塊級元素特性:html

  1. 老是獨佔一行
  2. 寬度,高度,內邊距,外邊距均可以設置
div {
    display: inline-block;//先用display:inline-block屬性觸發塊元素
    *zoom: 1;//經過zoom:1觸發塊元素的layout
    *display: inline;//讓塊元素呈x現爲內聯對象
}

XHTML和HTML有什麼區別前端

XHTML是更嚴格的HTML標準,主要表如今:XHTML元素必須正確的嵌套和關閉,標籤名必須用小寫字母,文檔必需要有根元素vue

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

  1. 結構層:主要指DOM節點,html
  2. 表現層:主要指頁面渲染,css
  3. 行爲層:主要指頁面的動畫效果,js

Doctype做用?標準模式與兼容模式各有什麼區別?java

  1. Doctype在文檔的第一行,處於html標籤以前。告訴咱們的瀏覽器用什麼文檔標準來解析文檔。Doctype不存在或格式不正確會致使文檔以兼容模式呈現。
  2. 標準模式:標準模式下的排版和js的運做模式都是按照該瀏覽器支持的最高標準來執行的。
  3. 兼容模式下,頁面以寬鬆的,向後兼容的方式顯示,模擬老式瀏覽器的行爲以防站點沒法工做。

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

對於標準模式,有嚴格型。對於準標準模式,有過渡型,框架集型。這兩種模式的差別幾乎能夠忽略不計。mysql

HTML5 爲何只須要寫 <!DOCTYPE HTML>?

HTML5不基於SGML(標準通用標記語言)的子集,所以不須要對DTD(文檔類型定義規則)進行引用。可是須要Doctype來規範瀏覽器的行爲。

html5有哪些新特性、移除了那些元素?如何處理HTML5新標籤的瀏覽器兼容問題?如何區分 HTML 和

HTML5?

新特性:

  1. 語義化更好的標籤:header,footer,nav,aside,article,section
  2. 對本地離線存儲更好的支持:localStorage長期存儲數據,瀏覽器關閉後數據不丟失。sessionStorage瀏覽器關閉後自動刪除。
  3. 畫布canvas,音頻audio,視頻video,地理Geolocation
  4. 新的表單控件:calendar,date,time,email,URL,search
  5. 新的表單元素:atalist 元素規定輸入域的選項列表。 keygen 元素的做用是提供一種驗證用戶的可靠方法。 output 元素用於不一樣類型的輸出
  6. webworker:當前javascript的主線程中,使用Worker類加載一個javascript文件來開闢一個新的線程,起到互不阻塞執行的效果,而且提供主線程和新線程之間數據交換的接口:postMessage,onmessage。
  7. JavaScript是單線程的,在執行過程當中會阻塞頁面的渲染和其餘腳本的執行。所以webworker能夠在主線程當中開啓一個新的線程,起到互不阻塞執行的效果。經過 worker = new Worker( url ) 加載一個JS文件來建立一個worker,同時返回一個worker實例。經過worker.postMessage( data ) 方法來向worker發送數據。綁定worker.onmessage方法來接收worker發送過來的數據。
  8. websocket:webscoket是HTML5提供的傳輸協議。它能夠將服務器的更新及時主動的發給客戶端

移除了純表現的元素:big,center,font,strike等等。對可用性產生負面影響的元素:frame,frameset,noframes;

瀏覽器兼容問題:IE8/IE7/IE6支持經過document.createElement方法產生的標籤,能夠利用這一特性讓這些瀏覽器支持HTML5新標籤。固然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架

如何區分:DOCTYPE聲明\新增的結構元素\功能元素

iframe的優缺點?

優勢:

  1. 解決加載緩慢的第三方內容如圖標和廣告等的加載問題
  2. Security sandbox
  3. 並行加載腳本

缺點:

  1. iframe會阻塞主頁面的Onload事件;
  2. 即時內容爲空,加載也須要時間
  3. 沒有語意

div+css的佈局較table佈局有什麼優勢?

  1. 改版的時候更方便 只要改css文件。
  2. 頁面加載速度更快、結構化清晰、頁面顯示簡潔。
  3. 表現與結構相分離。
  4. 易於優化(seo)搜索引擎更友好,排名更容易靠前。

<meta>文檔編碼格式 

http-equivcontent-type值能夠設計文檔的編碼格式。把 content 屬性關聯到 HTTP 頭部。

 <meta http-equiv='Content-Type' content='text/html; charset=gbk'>

CSS

頁面導入樣式時,使用link和@import有什麼區別?

  1. 就標籤的分類來講,link屬於HTML標籤,而@import是CSS提供的。並且link的權重大於@import。
  2. 加載順序來講,link引用的css文件,頁面載入的時候同時加載。而@import是等到頁面加載完成後再加載。
  3. 兼容性來講,link沒有兼容性問題,@import在IE5以上纔可識別
  4. 使用DOM控制樣式時,link支持js操做DOM改變樣式。@import不行。

CSS放在頂部/底部有什麼區別

  1. CSS放在頂部時,頁面會逐步呈現出來。由於瀏覽器在頁面載入的時候同時加載css。瀏覽器會根據html生成DOM樹,根據css生成渲染樹。
  2. 可是放在底部頁面會出現白屏或者閃跳的狀況。由於放在底部時,css是等頁面下載完後再被下載。瀏覽器爲了彌補樣式比較靠後的加載,爲了逐步呈現從而延遲呈現,所以出現白屏的狀況。

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

就是@import引發的。@import是等到頁面加載完成後再加載。所以會出現閃爍的感受。解決辦法是link引用css文件

簡要說一下CSS的元素分類

塊級元素:div p ul ol li form

行內元素:span a input img strong em label

CSS 選擇符有哪些?哪些屬性能夠繼承?優先級算法如何計算? CSS3新增僞類有那些?以及這些選擇器的使用場景?

選擇器:(按優先級)

  1. 通配符*   (*, > ,+ 選擇器的權重都是0)
  2. id選擇器 #myid (權重100)
  3. class選擇器 .class  (10)
  4. 屬性選擇器 input[type="button"](10)
  5. 僞類選擇器 a:link a:visited a:hover a:visited(10)
  6. 標籤選擇器 p div (1)
  7. 僞元素選擇器 a:before a:after :first-child(1)
  8. 相鄰+,子>,後代選擇器

優先級算法:同權重下以最近者爲準

!important>行內樣式(權重1000)>id選擇器(權重100)>id選擇器 |屬性選擇器|僞類選擇器 (權重10)>標籤選擇器|僞元素選擇器(權重1)

可繼承的樣式:font的樣式,color,visiblity

不可繼承的:關於盒模型的:width height margin padding border

新增僞類:first-child last-child nth-child(n)

CSS選擇器,nth-chlid(n)和nth-of-type(n)區別

ele:nth-of-type(n)是指父元素下第n個ele元素, 而ele:nth-child(n)是指父元素下第n個元素且這個元素爲ele,若不是,則選擇失敗

介紹一下CSS的盒子模型?

W3C標準盒模型:content,padding,border,margin。其中width指的是內容content的寬度

IE盒模型:content,padding,border,margin。其中width指的是content的寬度+padding+border的寬度

box-sizing經常使用的屬性有哪些?分別有什麼做用?

是CSS3中提供的屬性。主要控制盒模型的解析方式。每種盒模型計算元素寬高的方式不一樣:

  1. 它的默認值是content-box,也就是width的寬度指的是內容content的寬度。是W3C標準盒模型。
  2. border-box的width是content+padding+border。也就是IE盒模型
  3. 還有padding-box:width指的是content+padding的寬度。

display的值:

規定元素生成框的類型:

  1. block:塊類型元素
  2. inline:行內元素
  3. inline-block:行內塊級元素
  4. list-item:塊類型元素,並添加樣式列表標記
  5. none:元素脫離文檔流,不會顯示

display:none與visibility:hidden的區別是什麼?

他們均可以隱藏對應的元素。

  1. display:none:使元素脫離文檔流,不佔用空間。其餘元素會靠攏,就當他不存在同樣。
  2. visibility:hidden:不會脫離文檔流。

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

  1. relative:相對於其在普通流中的位置定位
  2. absolute:相對於離其最近的已定位的父元素定位,若是沒有就相對於窗口。
  3. fixed:相對於瀏覽器窗口定位。
  4. static:元素在正常流當中,而且忽略其top,bottom,left,right值
  5. inherit:從父元素繼承position的值

什麼要初始化CSS樣式?

由於瀏覽器的兼容問題,不一樣瀏覽器對某些標籤的默認值不一樣。若是沒有初始化,會致使頁面在不一樣瀏覽器中存在差別。

垂直居中設置(已知大小和未知大小,圖片)多行文本居中

已知大小:

塊元素:絕對定位後margin左上都設置爲負的1/2寬高。

.center{
        position: absolute;
        width: 200px;
        height: 200px;
        left:50%;
        top:50;
        margin-top:-100px;
        margin-left: -100px;
    }

文本:將文本text-align:center;line-height設置爲父容器的高;

  .text{
        height:100px;
        text-align: center;
        line-height: 100px;
    }

多行文本居中:width,height必須使用px單位,再配合vertial-align:middle和display:table-cell屬性,且div不能浮動,若是浮動就在裏面再添加一個div

.parent{
     display: table-cell;
     vertical-align: middle;
}

未知大小元素居中:

方法一:使用CSS3的flex-box

.wrap {
        display: flex;
        align-items: center;
        justify-content: center;
    }

方法2:父元素相對定位,子元素絕對定位,左右爲50%,再使用transform:translate上下移動自身的-50%;

.parent{
   position: relative;
}
.child{
    position: absolute;
    left: 50%;
    top: 50%; 
    -webkit-transform: translate(-50%,-50%);
}

方法4:給子元素加上table標籤,讓table的margin:0 auto;height:100%;

<table style="margin: 0 auto;height: 100%;">
            <tbody>
                <tr>
                    <td>
                        <ul ><!-- ul居中-->
                            <li>8888888888</li>
                            <li>8888888888</li>
                            <li>8888888888</li>
                            <li>8888888888</li>
                            <li>8888888888</li>
                        </ul>
                    </td>
                </tr>
            </tbody>
</table>

居中圖片:

.parent{
    display:table-cell;
    vertical-align:middle;
    text-align:center;
}

浮動原理,浮動產生的問題,CSS清除浮動的幾種方法(至少兩種)

浮動的元素脫離文檔流,不佔用空間。能夠向左和向右浮動,直到它的外邊緣碰到包含框或者另一個浮動框的邊緣爲止。

浮動產生的問題:

  1. 由於浮動的元素脫離文檔流,同級非浮動的元素會表現的他不存在同樣。
  2. 若是父元素沒有設置寬高,其子元素都浮動的話,會致使父元素的高度沒法撐開。影響與父元素同級的元素。

解決辦法:

  1. 同級的元素被覆蓋,能夠浮動同級元素,可是不推薦這種作法,由於後面的佈局會受到影響。也能夠給非浮動元素添加clear:both;
  2. 能夠在浮動元素的後面加上空標籤清除浮動
  3. 能夠給父元素添加一個after僞元素。也可讓父元素overflow:hidden/auto;*zoom:1;

CSS隱藏元素的幾種方法(至少說出三種)

  1. display:none;不佔用空間
  2. height:0;overflow:hidden
  3. visibility:hidden;佔用空間,不影響點擊事件
  4. opacity:0;

<strong>,<em>和<b>,<i>標籤

  1. strong:邏輯標記,粗體強調標籤表示內容的重要性
  2. em:斜體強調標籤,更強烈強調,表示內容的強調點
  3. b:物理標記,只是單純的加粗
  4. i:物理標記,單純的斜體

img的alt與title有何異同?

  1. alt:用於圖片的替代文字,當不能顯示圖片時顯示。
  2. title:用於提供元素的信息,鼠標懸停時顯示(在IE瀏覽器下會在沒有title時顯示alt)

px,em的區別

它們都是長度單位,px的值是固定的,指定多少就是多少,em的值是不固定的,他會繼承父級元素的大小。瀏覽器默認字體高都是16排序,因此未經調整的話1em=16px;

怎麼實現三角形?

寬高設爲0,border設置很大的寬度,再根據所須要的三角形方向設置border-left/right等。

#triangle-left {    
            width: 0px;    
            height: 0px;   
            border: 100px solid transparent;   
            border-right:  100px solid red;   
         } 

怎麼實現一個圓形可點區域?

1.border-radius設置成50%;

.circle {
        width: 100px;
        height: 100px;
        border-radius: 50%;
        cursor: pointer;
    }

2.map+area

<img src="t.jpg" width="1366" height="768" border="0" usemap="#Map" />  
    <map name="Map" id="Map">  
    <area shape="circle" coords="821,289,68" href="www.baidu.com" target="_blank" />  
</map>  

<area shape="circle" coords="x1, y1,r" href=url>表示設定熱點的形狀爲圓形,圓心座標爲(X1,y1),半徑爲r。

3.JS實現,獲取鼠標點擊位置座標,判斷其到圓點的距離是否不大於圓的半徑,來判斷點擊位置是否在圓內

document.onclick = function(e) {    
    var r = 50;   
    var x1 = 100;  
    var y1 = 100;  
    var x2= e.clientX;  
    var y2= e.clientY;    
    var distance = Math.abs(Math.sqrt(Math.pow(x2 - x1, 2) +      Math.pow(y2 - y1, 2)));    
    if (distance <= 50)  alert("Yes!");    
}  

css一個冒號和兩個冒號區別?

一個冒號用於CSS僞類,兩個冒號用於CSS僞元素。它是CSS3中引入的,爲了區分僞類和僞元素。爲了兼容IE,仍是用一個比較好。

兩欄分佈,左邊定寬右邊自適應。

左側固定寬度,讓他絕對定位。右側margin-left設爲左側寬度

.left{
           width:200px;
           height: 800px;
           position: absolute;
           left:0;
           top:0;
        }
.right{
       height: 800px;
       margin-left: 200px;
       background-color: green;
    }

三欄分佈

左側右側固定寬度而且絕對定位。中間設置marginleft和right。

        .left{
            width: 200px;
            position: absolute;
            left: 0;
            top: 0;
            height: 800px;
        }
        .right{
            width: 300px;
            position: absolute;
            right: 0;
            top: 0;
            height: 800px;
        }
         .main{ 
         /*     position: absolute; 
                      left: 200px;
                     right: 300px;  */
             margin-left: 200px;
             margin-right: 300px;
        } 

css hack原理和分類,利弊

原理:因爲不一樣的瀏覽器和瀏覽器各版本對CSS的支持及解析結果不同,以及CSS優先級對瀏覽器展示效果的影響,咱們能夠據此針對不一樣的瀏覽器情景來應用不一樣的CSS。

分類:

  1. CSS屬性前綴法 :IE6能識別下劃線"_"和星號" * ",IE7能識別星號" * ",IE6~IE10都認識"\9",但firefox前述三個都不能認識
  2. 選擇器前綴法:IE6能識別*html .class{},IE7能識別*+html .class{}或者*:first-child+html .class{}
  3. IE條件註釋法(即HTML頭部引用if IE)針對全部IE(注:IE10+已經再也不支持條件註釋): <!--[if IE]>IE瀏覽器顯示的內容 <![endif]-->,針對IE6及如下版本: <!--[if lt IE 6]>只在IE6-顯示的內容 <![endif]-->。這類Hack不只對CSS生效,對寫在判斷語句裏面的全部代碼都會生效。

利弊:使用hack雖然對頁面表現的一致性有好處,但過多的濫用會形成html文檔混亂不堪,增長管理和維護的負擔。

瀏覽器前綴

如今寫css3代碼的時候,爲了實現兼容性,須要在前面加前綴以便兼容對應的瀏覽器。

-webkit  //Webkit 谷歌和Safari瀏覽器
-moz  //Gecko內核,火狐瀏覽器
-o     //Presto內核,Opera瀏覽器
-ms  //Trident內核,IE瀏覽器

什麼是Css Hack?ie6,7,8的hack分別是什麼?

對不一樣的瀏覽器寫不一樣的CSS的過程,就是CSS hack

 background-color:red\9;      /*all ie*/
 background-color:yellow\0;    /*ie8*/
+background-color:pink;        /*ie7*/
 _background-color:orange;       /*ie6*/ 

解釋下 CSS sprites,以及你要如何在頁面或網站中使用它。

把網頁中一些背景圖片整合到一張圖片文件中。利用CSS的background-image,background-position組合進行定位。減小HTTP請求次數。

對BFC規範的理解?

塊級格式化上下文,是CSS2.1提出的一個概念:它決定了元素如何對其內容進行佈局,以及和其餘元素的關係和相互做用。一個建立了BFC的盒子是獨立佈局的,盒子裏面的元素的樣式不會影響到外面的元素。

Css渲染機制

在網頁中的應該使用奇數仍是偶數的字體?爲何呢?

  1. 偶數字號相對更容易和 web 設計的其餘部分構成比例關係
  2. 爲了遷就ie6,ie6會把定義爲13px的字渲染成14px
  3. 偶數寬的漢字顯得均衡

iconfont矢量圖標優勢和缺點

Iconfont 就是指用字體文件取代圖片文件,來展現圖標、特殊字體等元素的一種方法。

優勢:

  1. 加載文件體積小。
  2. 能夠直接經過css的font-size,color修改它的大小和顏色,對於須要縮放多個尺寸的圖標,是個很好的解決方案。
  3. 支持一些css3對文字的效果,例如:陰影、旋轉、透明度。
  4. 兼容低版本瀏覽器。

缺點:

  1. 矢量圖只能是純色的。
  2. 製做門檻高,耗時長,維護成本也很高。

知道的網頁製做會用到的圖片格式有哪些?

  1. png-8,png-24,jpeg,gif,svg,Webp,Apng
  2. Webp:谷歌開發的爲了加快圖片下載速度的圖片格式。它的圖片大小隻有JPEG的2/3.
  3. Apng:能夠實現png格式的動態圖片效果

canvas爲何會出現,用來作什麼的;

canvas 元素使用 JavaScript 在網頁上繪製圖像,適合像素處理,動態渲染和大數據量繪製

簡述一下src與href的區別。

  1. src用於替換當前元素,指向外部資源的位置,指向的內容會嵌入到文檔當中,它會阻塞其餘資源的下載。直到該資源下載執行完畢。好比js腳本,image圖片等
  2. href指向網絡資源所在的位置,它會並行下載資源而且不會中止對當前文檔的處理,好比link方式引入css文件。

什麼是外邊距重疊?重疊的結果是什麼?

CSS中相鄰兩個盒子的外邊距會結合成一個單獨的外邊距,這種合併的方式稱爲摺疊。兩個浮動的塊元素不存在margin摺疊的狀況

摺疊結果遵循如下原則:

  1. 兩個相鄰的外邊距都是正數時,摺疊結果是它們二者之間較大的值
  2. 兩個相鄰的外邊距都是負數時,摺疊結果是二者絕對值的較大值
  3. 兩個外邊距一正一負時,摺疊結果是二者的相加的和

兩個塊狀元素上下的margin-top和margin-bottom會重疊。啥緣由?怎麼解決?

CSS中相鄰兩個盒子的外邊距會結合成一個單獨的外邊距,這種合併的方式稱爲摺疊。

而對於標準瀏覽器來講:兩個浮動的塊元素不存在margin摺疊的狀況,可是此時加浮動後會形成IE6的雙邊距bug,可讓其設置爲_diplay:inline;

rgba()和opacity的透明效果有什麼不一樣?

都能實現透明效果。opacity會做用於元素的背景和內容,rgba只會做用於背景。

關於letter-spacing的妙用知道有哪些麼?

以用於消除inline-block元素間的換行符空格間隙問題。

Sass、LESS是什麼?你們爲何要使用他們?

他們是CSS預處理器,他們是一種特殊的語法/語言編譯成CSS。例如LESS是一種動態樣式語言. 將CSS賦予了動態語言的特性,如變量,繼承,運算, 函數. LESS 既能夠在客戶端上運行 (支持IE 6+, Webkit, Firefox),也可一在服務端運行 (藉助 Node.js)

爲何要使用它們?

  1. 結構清晰,便於擴展。
  2. 能夠方便地屏蔽瀏覽器私有語法差別。
  3. 能夠輕鬆實現多重繼承。
  4. 徹底兼容 CSS 代碼,能夠方便地應用到老項目中。

知道css有個content屬性嗎?有什麼做用?有什麼應用?

用在before和after僞元素上,用來插入生成內容。

最多見的應用就是清除浮動:

.parent:after{
    content:'.';
    height:0;
    visiblity:hidden;
    display:block;
    clear:both;
    *zoom:1;   // for IE6
} 

去除inline-block間隙的方法

  1. 去除標籤內的空格和換行符(代碼可讀性變差,中間能夠加註釋分開)
  2. inline-clock的元素設一個負的margin值:3px;margin負值的大小與上下文的字體和文字大小相關
  3. 父元素設置font-size:0;-webkit-text-size-adjust:none;
  4. 使用letter-spacing字符間距:父元素letter-spacing: -3px;inline-clock的元素設letter-spacing: 0px;
  5. 使用word-spacing單詞間距:父元素word-spacing: -6px;inline-clock的元素設letter-spacing: 0px;word-spacing的負值只要大到必定程度,其兼容性上的差別就能夠被忽略

媒體查詢

使用@media能夠針對不一樣的媒體類型或者不一樣屏幕大小來定義不一樣的樣式

@media screen and/not/only (min-width:365px,max-width:667px;)//iphone6
@media screen and/not/only (min-width:768px,max-width:1024px;)//ipad
@media screen and/not/only (min-width:1024px)//sm-screen

 

Css實現動畫效果Animation還有哪些其餘屬性。

CSS3動畫的屬性主要分爲三類:

transform

  1. 元素順時針旋轉的角度rotate
  2. 設置元素放大或縮小的倍數scale
  3. 設置元素的位移translate
  4. 設置元素傾斜的角度skew

transition過渡:能夠在不使用 Flash 動畫或 JavaScript 的狀況下,當元素從一種樣式變換爲另外一種樣式時爲元素添加效果。

animation:@keyframes 規則用於建立動畫。在 @keyframes 中規定某項 CSS 樣式,就能建立由當前樣式逐漸改成新樣式的動畫效果

怎麼在頁面裏放置一個很簡單的圖標,不能用img和background-img

canvas,icon庫

談一談flexbox,講一講哪些瀏覽器已經支持。

彈性佈局。把複雜的網站佈局變得簡易和快速。

若是咱們把Flexbox新語法、舊語法混合在一塊兒使用,在現代瀏覽器(Chrome、Firefox、Safari、Opera Presto 12.1+,IE10+,IOS和Android)能夠獲得很好的支持。在這裏新舊語法的順序顯得很是重要。須要確保老語法不要覆蓋新語法。寫的時候對於不一樣的瀏覽器加上不一樣的前綴。

任何一個容器均可以指定爲Flex佈局,它有以下屬性(主軸排列方向flex-direction,是否換行flex-wrap,主軸對齊方式justify-content,與主軸垂直的對其方式align-content):

.flex-container {
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
   /*主軸方向:項目排列方向水平*/
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
  /*超出容器後是否換行:換行*/
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
  /*主軸對齊方向:水平居中*/
    -webkit-justify-content: center;
    -ms-flex-pack: center;
    justify-content: center;
  /*垂直方向的對齊方式:垂直居中*/
    -webkit-align-content: center;
    -ms-flex-line-pack: center;
    align-content: center;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    }

你瞭解哪些佈局?你平時有使用過什麼佈局實現?

  1. 浮動佈局
  2. 彈性盒模型佈局:主要解決移動端屏幕寬度不定的問題。
  3. 定位佈局

DOM

DOM操做——怎樣添加、移除、移動、複製、建立和查找節點。

  1. createAttribute() 建立屬性節點。
  2. createElement() 建立元素節點。
  3. createTextNode() 建立文本節點。
  4. parent.removeChild(child);
  5. parent.replaceChild(new,old);
  6. parent.appendChild(child)
  7. parent.insertBefore(before,old)
  8. getElementById("id")
  9. getElementsByClassName("class")
  10. getElementsByTagName("p")

NodeList和Array的區別

NodeList是DOM操取出來的集合,是集合而不是普通的數組,所以不能使用數組元素的方法來操做nodelist

NodeList具備length,下標索引這些數組的屬性特徵

NodeList最大的特色就是時效性(live),這個集合是「動態的」:每當文檔結構發生變化時,它會獲得更新,所以在迭代nodelist的時候,應該將其length緩存到變量值,不然有可能會形成無限循環的問題,並且應該儘可能減小訪問nodelist的次數,由於每次訪問nodelist都會進行一次基於文檔的查詢,咱們應該將nodelist中取得的值緩存起來。

另外,咱們能夠把NodeList轉化爲數組,方便操做

在IE8+和其餘瀏覽器當中能夠使用

Array.prototype.slice.call(nodelist,0)

在IE中必須手動枚舉成員

使用try-catch

另外ES6當中提供了Array.from()將類數組對象轉化爲數組var brr=Array.from(nodelist);

function converToArray(nodelist) {
        var arr = [];
        var len = nodelist.length;
        try {
            arr = Array.prototype.slice.call(nodelist, 0)); //針對非IE瀏覽器
            } catch (error) {

              for (var i = 0; i < len; i++) {
                  arr.push(nodelist[i])
                 }
        }
        return arr;
    }

事件委託是什麼?事件委託的缺點

事件委託:是 JavaScript 中綁定事件的經常使用技巧,利用事件模型中的冒泡原理,將事件綁定在更上層的父元素時,經過檢查事件的目標對象來判斷並獲取事件源。使用事件代理的好處是能夠提升性能。

使用場景:

  1. 給許多子元素綁定相同的事件,好比ul的li元素,或者table的td元素。能夠大量節省內存,減小事件註冊。
  2. 能夠實現當新增子對象時無需再次綁定事件,對於動態內容及其合適

缺點:事件代理的經常使用應用應該僅限於上述需求,若是把全部事件都用事件代理,可能會出現本不應被觸發的事件被綁定上了事件的狀況。

DOM0和DOM2的區別

  1. DOM0中事件一旦發生就直接調用事件句柄,無傳播過程。在DOM2中有一個事件的傳播過程。包括事件捕獲,目標元素的事件處理程序運行,事件冒泡。
  2. 一個DOM對象註冊多個類型相同的事件時,DOM0級中會發生事件的覆蓋,而DOM2級中則會依次執行各個事件函數。
  3. DOM0級事件的註冊是直接將事件處理程序做爲js對象的屬性,或者是將js代碼做爲HTML元素的性質值。在DOM2中,事件的註冊能夠使用addEventListener("click",fn,false)的方法。事件刪除用removeEventListener()

冒泡和捕捉

  1. 事件捕捉:事件由document對象一直向下傳播到目標元素
  2. 事件冒泡:事件從目標元素上升一直打到document

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

  1. IE:window.event.cancelBuble=true;
  2. DOM2:ev.stopPropogation();
  3. 阻止默認行爲:return false;

事件模型

在各類瀏覽器中存在3種事件模型:

1.DOM0(全部瀏覽器都支持):

  1. DOM0中事件一旦發生就直接調用事件句柄,無傳播過程
  2. 一個DOM對象註冊多個類型相同的事件時,DOM0級中會發生事件的覆蓋
  3. DOM0級事件的註冊是直接將事件處理程序做爲js對象的屬性,或者是將js代碼做爲HTML元素的性質值。

2.DOM2(除了IE意外都支持)

  1. 在DOM2中有一個事件的傳播過程。包括事件捕獲,目標元素的事件處理程序運行,事件冒泡。
  2. DOM2級中一個DOM對象註冊多個類型相同的事件時,則會依次執行各個事件函數。
  3. 在DOM2中,事件的註冊能夠使用addEventListener("click",fn,false)的方法。事件刪除用removeEventListener()
  4. event對象是事件處理函數的參數,事件源是e.target

3.IE事件模型:

  1. IE的事件傳播過程只有DOM0級和DOM2級中第二第三階段,也就是隻冒泡,不捕捉。
  2. ie中也能夠在一個對象上添加多個事件處理函數
  3. 事件的註冊用attachEvent("onclik",fn);事件刪除用detachEvent();
  4. IE中的event對象不是事件處理函數的參數,而是window,而且事件源是srcElement

document.write()用法,和innerHTML區別?

document.write()方法能夠用在兩個方面:

  1. 頁面載入過程當中用實時腳本建立頁面內容
  2. 用延時腳本建立本窗口或新窗口的內容。

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

window.onload和$(document).ready區別?用原生實現

window.onload()方法是必須等到頁面內包括圖片的全部元素加載完畢後才能執行。

$(document).ready()是DOM結構繪製完畢後就執行,沒必要等到加載完畢。

function ready(fn){
    if(document.addEventListener) {        //標準瀏覽器
        document.addEventListener('DOMContentLoaded', function() {
            //註銷事件, 避免反覆觸發
            document.removeEventListener('DOMContentLoaded',arguments.callee, false);
            fn();            //執行函數
        }, false);
    }else if(document.attachEvent) {        //IE
        document.attachEvent('onreadystatechange', function() {
            if(document.readyState == 'complete') {
                document.detachEvent('onreadystatechange', arguments.callee);
                fn();        //函數執行
            }
        });
    }
};

attribute和property的區別是什麼?

  1. attribute是dom元素在文檔中做爲html標籤擁有的屬性;
  2. property就是dom元素在js中做爲對象擁有的屬性。

因此:

  1. 對於html的標準屬性來講,attribute和property是同步的,是會自動更新的,
  2. 可是對於自定義的屬性來講,他們是不一樣步的,

dom3新增長了哪些特性,哪些已經被徹底接受了

事件循環

如何在頁面中插入一些數據

原生js添加class怎麼添加,若是自己已經有class了,會不會覆蓋,怎麼保留?

document.getElementById("flag").className = "mycalss"

 

 

JavaScript

eval是作什麼的?

  1. 做用:把對應的字符串解析成js代碼並運行,返回執行的結果。
  2. 缺點:應該避免使用eval,由於不安全,很是耗性能(兩次,一次解析成js語句,一次執行)
  3. 應用場景:把json字符串轉化爲json對象。

js有哪些內置對象?

  1. Object,Array
  2. Boolean,Number,String
  3. Math,Date,Function,RegExp,Error,Argument,Global

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

延遲javascript代碼的加載是爲了加快網頁的訪問速度

1.把延遲腳本放在頁面底部(body標籤裏):若是把script標籤放在head中,那麼js加載完後纔會加載頁面,由於js會阻塞後面的代碼的運行。這時候能夠放在頁面的底部,文檔會按照從上到下的順序加載。

2.動態建立DOM的方式:在文檔都加載完後,建立script標籤,插入到DOM中

//這些代碼應被放置在</body>標籤前(接近HTML文件底部)
<script type="text/javascript">
    function downloadJSAtOnload() {
        var element = document.createElement("script");
        element.src = "defer.js";
        document.body.appendChild(element);
    }
    if (window.addEventListener)
        window.addEventListener("load", downloadJSAtOnload, false);
    else if (window.attachEvent)
        window.attachEvent("onload", downloadJSAtOnload);
    else window.onload = downloadJSAtOnload;
</script>

3.defer:在script標籤裏設置這個屬性,腳本會被延遲到整個頁面都解析完畢後再運行,就是至關於告訴瀏覽器當即下載但延遲執行。

4.async:它的做用和defer相似,可是不能控制加載的順序。

<script src="" async="true"/>

5.使用在文檔加載完後使用setTimeout()方法延遲加載js:

window.onload=function(){
    setTimeout(function(){
        var head=document.getElementsByTagName("head")[0];
        var script=document.createElement("script");
        script.src="defer.js";
           head.appendChild("script")
    },1000)
}

六、使用jQuery的$.getScript( "src",callback )方法

$.getScript("defer.js",function(){
    console.log("回調函數執行"); })

什麼是 「use strict」; ? 使用它的好處和壞處分別是什麼?

它是JavaScript另外的一種運行模式,在這種模式下,JavaScript在更嚴格的條件下執行。

好處:

  1. 消除JavaScript一些不合理不嚴謹之處,消除一些怪異行爲。
  2. 保證代碼安全運行
  3. 提升編譯器效率,增長運行速度。
  4. 爲將來版本的JavaScript作好鋪墊。

壞處:

如今網站的js都會進行壓縮,一些文件用了嚴格模式,一些文件沒有,壓縮後原本是嚴格模式的文件,不只沒有指示嚴格模式,反而在壓縮後浪費了字節。(能夠寫在當即執行函數當中)

說說嚴格模式的限制

  1. 變量必須先聲明後使用
  2. 函數的參數不能有同名屬性,不然報錯
  3. 對象不能有同名的屬性
  4. 不能對只讀屬性賦值
  5. 不能刪除不可刪除的屬性
  6. eval和arguments不能被從新賦值
  7. arguments不會自動追蹤函數參數的變化,傳進來是幾就是幾
  8. 不能使用arguments.callee和arguments.caller
  9. 禁止設置原始類型的屬性
  10. 禁止八進制表示法
  11. 新增保留字,不能講保留字做爲變量名 let const static private public yield package 

JavaScript 運行機制詳解

寫一個鏈式調用;

鏈式調用就是一行代碼就實現了對一個或多個節點的兩個或兩個以上的操做。好比jquery裏面就實現了鏈式操做:對一個節點進行屢次的操做

實現鏈式操做的核心思想是在每一個對象的方法裏面都返回這個對象:

/*建立對象的方式:組合使用構造函數模式和原型模式:構造函數模式定義屬性,
原型模式定義對象的方法,用原型模式能夠實現全部對象的實例共享它的方法,
這樣能夠最大限度的節省內存*/
function Base(){
    // 把返回的節點保存在一個數組裏頭
    this.elements=[];
    /*獲取id*/
    this.getId=function(id){
        //獲取到對象後放在數組裏面
          this.elements.push(document.getElementById(id));
            //在對象的方法中返回這個對象
          return this;
     };
    this.getClass=function(className){
          this.elements.push(document.getElementsByClassName(className));
          return this;
     };
    this.getTag=function(tag){
          this.elements.push(document.getElementsByTagName(tag));
          return this;
     };
    this.getName=function(name){
          this.elements.push(document.getElementsByName(name));
          return this;
     };

}
//給原型對象添加方法,全部實例共享這些方法
Base.prototype.css=function(attr,value){
    for (var i = 0; i < this.elements.length; i++) {
        this.elements[i].style[attr]=value;
    }
    return this;
}

Base.prototype.html=function(str){
    for (var i = 0; i < this.elements.length; i++) {
        this.elements[i].innerHTML=str;
    }
    return this;
}

Base.prototype.click=function(fn){
    for (var i = 0; i < this.elements.length; i++) {
        this.elements[i].onclick=fn;
    }
    return this;
}
//避免在前臺new一個對象
var $=function(){
    return new Base();
}
//在前臺就能夠使用庫當中的代碼了
window.onload=function(){
    console.log($().getId("id").css("color","red").html("hello world"));
}

瞭解設計模式嗎(我說了單例和觀察者模式,並寫了下代碼,介紹有啥做用)

js異步的方法(promise,generator,async)

在瀏覽器端,異步編程很是重要,耗時很長的操做都應該異步執行,避免瀏覽器失去響應。

在ES6以前,異步編程的方法大概有如下幾種

回調函數:將回調函數做爲異步函數的參數傳入,至關於先執行程序的主要邏輯,將耗時的操做推遲執行,這種方法不利於代碼的維護,代碼高度耦合

發佈訂閱模式:假設存在一個信號中心,某個任務執行完成後向信號中心發佈一個信號,其餘任務能夠向信號中心訂閱這個信號,從而知道本身何時能夠執行,這樣去除了代碼之間的耦合,並且咱們能夠經過查看消息中心能夠知道有多少個信號,每一個信號有多少個訂閱者

這個模式有多種實現,咱們能夠用jquery的插件

Promises對象是CommonJS工做組提出的一種規範,目的是爲異步編程提供統一接口,使得控制異步操做更加的容易。promise優勢在於避免層層嵌套的回調函數,回調函數變成了鏈式寫法,程序的流程能夠看得很清楚。並且若是一個任務已經完成,再添加回調函數,該回調函數會當即執行。因此,你不用擔憂是否錯過了某個事件或信號。

 generator函數:多個線程相互合做,完成異步任務

async函數:generator函數的改進

 

類型,值和變量

判斷類型的方法

  1. 原始類型使用typeof操做符(string,number,undefined,object,boolean,function,symbol)
  2. 引用類型使用 x instanceof class(Array,Object)
  3. 還有因此類型通用的Object.prototypr.toString.call(o) //String,Number,Boolean,Object,Array,Null,Undefined,Function

javascript的typeof返回哪些數據類型?

返回字符串:string,number,undefined,object,boolean,function,symbol

例舉3種強制類型轉換和2種隱式類型轉換?

      強制:有三個函數能夠將非數值轉化爲數值:parseInt,parseFloat,(將字符串轉化爲數值)number(適用於任何數據類型)

      隱式:==  

null和undefined的區別?

null是一個表示"無"的對象,轉爲數值時爲0;undefined是一個表示"無"的原始值,轉爲數值時爲NaN。

當聲明的變量還未被初始化時,變量的默認值爲undefined。null用來表示還沒有存在的對象,經常使用來表示函數企圖返回一個不存在的對象。

undefined表示"缺乏值",就是此處應該有一個值,可是尚未定義。典型用法是:

  1. 變量被聲明瞭,但沒有賦值時,就等於undefined。
  2. 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
  3. 對象沒有賦值的屬性,該屬性的值爲undefined。
  4. 函數沒有返回值時,默認返回undefined。

null表示"沒有對象",即該處不該該有值。典型用法是:

  1. 做爲函數的參數,表示該函數的參數不是對象。
  2. 做爲對象原型鏈的終點。

JavaScript中的變量聲明提高?

在一個函數體內,不管在哪聲明的變量,都會被提高到函數的頂部,再依次從上到下執行和賦值。

數組

數組方法有哪些?

能改變原數組的:

    1. pop()  返回被刪除的最後一個元素
    2. push(item1,item2) 在後面添加元素,返回新的長度
    3. shift()  返回被刪除的第一個元素
    4. unshift(item1,item2) 在前面添加元素,返回新的長度
    5. sort(function(a,b){return b-a(倒序)|a-b(升序)})排序,字母按照開頭字母順序,若是排列數字大寫必須寫比較函數不然有bug
    6. reverse()  顛倒順序
    7. splice(index,howmany,newitem1,newitem2(加到被刪除的位置))返回被刪除元素組成的數組

不能改變原數組的

    1. slice(start,end)返回數組中的成員數組,包括end
    2. concat(newarr)返回鏈接後的新數組
    3. join(str)把數組值用指定字符串連起來,若是沒有就默認是逗號
    4. toString()把數組中的每一項用逗號鏈接起來轉化爲字符串(和沒參數的join同樣)

      ES5中的數組方法:

    1. arr.forEach(function(e,index,arr){}):給每一個元素調用指定的函數,不能停止遍歷
    2. arr.map(function(e,index,arr){return e*e}):每一個元素調用函數,有返回值,返回新的數組,不改變原數組,會處理稀疏數組,返回稀疏
    3. arr.filter(function(e){return e<3})返回知足條件的子數組,不會處理稀疏數組
    4. arr.every(function(e){return e<3}),看數組全部元素是否知足某條件,返回T/F
    5. arr.some(function(e){return e<3}),判斷數組的某些元素是否知足某條件,返回T/F
    6. arr.reduce(function(x,y){return x+y},0(初始值)):用指定的函數組合數組元素,返回單個值,初始值不提供的話將數組第一個和第二個做爲函數的參數

數組遍歷:

  1. 常規for循環(按照順序,會處理稀疏數組不存在的元素,也會處理null和undefined)
  2. for-in語句(不必定按順序,不會處理稀疏數組不存在的元素,保證兼容性使用前判斷null或者undefined)
  3. forEach()

寫出2個以上數組去重的方法:

1.建立一個新的數組存放結果,遍歷數組元素,判斷新數組在是否存在該元素,不存在就存入

function delSame(arr) {
                var result = [];
                var len = arr.length;
                for (var i = 0; i < len; i++) {
                    if (result.indexOf(arr[i]) == -1) {
                        result.push(arr[i])
                    };
                };
                return result;
            }

2.先將原數組排序,建立新數組並將第一個元素存入新數組,從第二項遍歷數組元素,判斷每一項和新數組最後一項是否相同,不相同存入該數組

function delSame2(arr) {
                var arr=arr.sort();
                var result=[arr[0]];
                var len = arr.length;
                for (var i = 1; i < len; i++) {
                    if (arr[i]!==result[result.length-1]) {
                        result.push(arr[i])
                    };
                };
                return result;
            }

3,建立一個新的結果數組和空對象,遍歷數組元素,判斷對象中屬性爲數組元素的值是否爲空,若是爲空,將元素存入結果數組,並將對象的屬性賦值爲1

function delSame3(arr) {
    var result=[];
    var obj={};
    var len=arr.length;
    for (var i = 0; i < len; i++) {
        var key=arr[i];
        if (!obj[key]) {
            result.push(arr[i]);
            obj[key]=1;
        };
    };
    return result;
}

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

 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 arguments.callee(left).concat(numValue,arguments.callee(right));//遞歸不斷重複比較
    }
    alert(quickSort([32,45,37,16,2,87]));//彈出「2,16,32,37,45,87」

判斷數組的方法:

  1. Array.isArray([])  //true
  2. [] instanceof Array  //ture(但這個方法在多個窗口中有可能會形成混淆,由於一個窗口中的對象有可能不是另外一個窗體中的構造函數的實例)
  3. Object.prototype.toString.call(arr)=='[object Array]'  //檢查對象的類屬性(最通用的)

函數

Javascript垃圾回收方法?

  1. 標記清除:這是全部瀏覽器最經常使用的一種垃圾回收方式,當變量進入環境(在函數在聲明一個變量)時,將其標記爲「進入環境」,當變量離開環境(函數執行結束)時,將其標記爲離開環境。垃圾收集器會按照固定的時間間隔週期性的釋放內存。
  2. 引用計數:當聲明瞭一個變量並將一個引用類型的值賦給該變量時這個值得引用次數+1,當去掉這個引用時,引用次數-1,當引用次數爲0時代表可將其內存回收

內存泄漏是什麼?

  1. 內存泄漏指任何對象在您再也不擁有或須要它以後仍然存在。
  2. 在低版本的IE中常常會出現內存泄漏,是由於IE中DOM/BOM對象都是經過引用計數回收的,由於存在循環引用的問題,因此他們的引用次數永遠不會爲0,假如這個函數被重複屢次調用,就會致使內存泄漏(大量內存得不到回收)
  3. 解決辦法:要想破壞循環引用,引用DOM元素的對象或DOM對象的引用須要被賦值爲null

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

  1. 閉包:閉包中的變量不會被垃圾回收機制回收。
  2. setTimeout 的第一個參數使用字符串而非函數的話,會引起內存泄漏。
  3. 循環引用:循環(在IE中兩個DOM/BOM對象彼此引用時,就會產生一個循環)

談談This對象的理解。

this老是指函數運行時所在的對象。在不一樣的場景中,this的身份不一樣:

    1. DOM的事件處理函數中,this指觸發這個事件的DOM對象;
    2. 全局函數調用中,this指window;
    3. 做爲對象的方法調用時,this指調用這個函數的那個對象;
    4. 用new實例化對象,做爲構造函數調用時,this指新建立的那個對象

ES6中,箭頭函數當中的this指的的是定義時所在的對象而不是使用時所在的對象。這樣咱們在使用的時候就不會產生不少歧義了。

JavaScript有塊做用域嗎?

沒有。在JavaScript中,if/for語句中初始化變量的表達式中所定義的變量,在循環結束後也依舊會存在於循環外部的執行環境當中。

JavaScript的做用域和做用域鏈?

  1. 做用域:只有函數纔會產生做用域的概念,它指變量的做用範圍,內部做用域由局部變量,函數,形參,實參組成
  2. 做用域鏈:保證執行環境中有權訪問的變量和函數是有序的,做用域鏈的變量只能向上訪問,變量訪問到window對象終止,變量做用域鏈向下訪問變量時不容許的。

說說函數表達式和函數聲明的區別

  1. 執行代碼時,JavaScript引擎在第一遍會聲明函數並將它們提高到頂部。因此函數聲明語句能夠它定義以前出現的代碼所調用。
  2. 函數表達式定義的函數,是將其賦值給一個變量,雖然變量的聲明提早了,但給變量賦值是不會提早的,所以調用這個函數以前必須先定義才行。

函數聲明提高:

執行代碼時,JavaScript引擎在第一遍會聲明函數並將它們提高到頂部。函數聲明語句能夠它定義以前出現的代碼所調用。

js中上下文是什麼,js有哪些函數能改變上下文

  1. 上下文就是this關鍵字的值,好比當函數做爲對象的方法來調用時,該對象就是這次調用的上下文,也就是該函數的this值;當函數做爲全局函數調用時,上下文指的時window。
  2. 做用域和上下文之間最大的區別是: 上下文在運行時肯定,隨時可能改變;做用域在定義時肯定,永遠不會改變。
  3. JavaScript中call和apply能夠改變上下文

call和apply的區別和做用?

區別:

  1. call()的第一個參數是上下文,第二個參數是參數序列
  2. apply()的第一個參數是上下文,第二個參數是參數組成的數組

做用:改變函數的上下文,它是以某個對象的方法來調用函數,函數的this指的是第一個參數。若是沒有傳遞參數是null/undefined,this指window

f.call(o)  //以對象o的方法來調用函數f
代碼的功能:
o.m=f; //將f存儲爲o的臨時方法
o.m(); //調用它,沒有參數
delete o.m //將臨時方法刪除

談談你對閉包的理解,爲何使用閉包,使用場景,它會有什麼影響?

  1. 閉包:就是訪問函數內部變量的函數,建立閉包的方式就是函數嵌套函數
  2. 做用:當在函數內部嵌套一個函數時,就建立了閉包,閉包能夠訪問它被定義時所處的做用域中的任何變量,而且參數和變量不會被垃圾回收機制回收。閉包還能夠避免全局變量的污染。
  3. 使用場景:在大型項目當中,爲了防止命名衝突,通常會把相應的代碼用閉包的形式包裹起來,避免暴露在全局做用域下
  4. 缺點:若是閉包引用外部變量,變量會常駐內存,這樣會增大內存使用量,從而下降性能,使用不當很容易形成內存泄露。

手寫一個閉包

function fn(){
    var n=0; function fn1(){ n++; console.log(n); } return fn1; } var foo=fn(); foo(); //1 foo(); //2 foo(); //3

new操做符具體作了什麼?

  1. 建立了一個空對象,而且this變量引用該對象,同時繼承了該函數的原型
  2. 屬性和方法加入到this引用的對象
  3. 新建立的對象由this引用,而且最後隱式的返回this
var o={};
o.__proto__=Base.prototype;
Base.call(o);

給你一個空函數,加new和不加new的區別

  1. 加new時,會把這個函數看成是一個構造函數,返回一個對象。
  2. 不加new時,就是調用一個普通的函數,結果視函數返回值而定。

 

for函數裏面setTimeout異步問題

setTimeout()是將一段代碼延遲必定時間並異步執行。好比想要在for循環裏面使變量i每隔1秒輸出,若是這樣寫:

for (var i = 1; i <= 2; i++) {
    setTimeout(function() { alert(i) }, 1000);
}

結果是兩次都彈出了3。由於setTimeout是異步的,那麼在調用它以前,其實3次循環都已經結束了。每一個定時器處理函數就會共享同一做用域裏的同一變量"i"。怎麼樣才能達到預期效果?你要每一個定時器處理函數建立不一樣的「i」變量副本

在函數內建立一個當即執行函數,函數引用了變量i,做爲實參將其傳遞給形參,從而建立變量副本。因爲setTimeout()副本上下文中調用的,因此它每次都本身的私有的"i"以供使用

for (var i = 1; i <= 2; i++) {
    (function(i) {
        setTimeout(function() { alert(i) }, 1000);
    })(i);
}

對象

定義不可修改屬性?

Object.defineProperty(obj,propertyName,{
     writable:false,  //表示可否修改屬性的值,默認是true
     configurable:false,  //表示不能從對象中刪除屬性,默認是true
     value:"valueOfProperty", //屬性的值,默認是undefined
     Enumerable:"true"          //可以經過for-in循環 ,默認是true
    })

對象屬性的遍歷

1.for-in循環能夠遍歷對象全部 可枚舉的(對象繼承的方法不可枚舉) ,包括自有的和繼承的屬性。

var o = {
    name: "lifurong",
    age: 24
}
for (var key in o) { 
    console.log(o[key])
};

//lifurong
//24

二、Object.keys()方法

返回一個由對象中可枚舉的自有的屬性組成的數組。

三、Object.getOwnPropertyNames()

返回一個由對象中全部的(包括不可枚舉的)自有屬性組成的數組。

Javascript中,有一個函數,執行時對象查找時,永遠不會去查找原型,這個函數是?

    obj.hasOwnProperty(propertyName);這個方法返回一個布爾值。用來檢測一個屬性是存在於實例中仍是存在於原型中。

object和array的區別

    數組表示帶有編號的有序數據的集合,而對象表示無序數據的集合。若是數據的順序很重要,就用數組,不然就用對象。

如何判斷對象的類型

  1. 用instanceof操做符來測試實例與原型鏈中出現的構造函數:b1 instanceof Box        //true
  2. 使用原型的isPrototypeOf()方法:Box.prototype.isPrototypeOf(b1)   //true

instanceof原理 

instanceof操做符是來測試實例與原型鏈中出現的構造函數。若是實例的原型鏈中有這個構造函數,返回true.

對象中key-value的value怎麼再放一個對象。

經過對象字面量的方法

var book={
   edition:2,
   author:{
         firstname:"David",
         lastname:"li"
    }
}

靜態屬性怎麼繼承?

靜態屬性:無需實例化就能夠調用的方法就叫靜態方法

靜態屬性不能被繼承

function Father() {
    //公有屬性
    this.lastname = "li";
    //私有屬性
    var mood="good";
}
     //靜態屬性
   Father.staticPro="staticPro";

function Child() {
    this.age = 20;
}
Child.prototype = new Father();

 

正則

匹配模式:i (忽略大小寫),g(全局:匹配全部字符串,而不是發現第一個就中止),m(多行模式:忽略文本的末尾)

regexp的方法:

  • test() : pattern.test(str)   返回T/F
  • exec(): pattern.exec(str)  返回數組,第一個是匹配的字符串,後面都是括號裏的子表達式的字符串

字符串方法:

  • search(pattern):返回第一個匹配字符串的起始位置
  • replace(pattern,str/fn):先找,而後替換,若是有g替換因此匹配字符串,沒有就替換第一個匹配的,函數能夠動態改變字符串(不改變原字符串)
  • match(pattern):返回數組,若是有g返回全部匹配結果,若是沒有數組第一個是字符串,剩下都是括號裏的子表達式

經常使用的正則:

  • \s空格,\d數字,\w(字母和數字),[^..]不在裏面的任意字符,+ 一個或多個,* 0個或多個, ?0或1個,{n}n個,{n,m} n<=x個<m
  • 字符類:中括號匹配一個所包含的任意字符 好比[ab]就是a或b,好比[3457]匹配3或者4或者5或者7,而(3457)只匹配3457

檢驗網址的正則:

var str="visit my personal information at http://www.t1amo.com/about.html"

var pattern=/(\w+):\/\/([\w.]+)\/(\S*)/

var result=str.match(pattern);

result[0] // http://www.t1amo.com/about.html

result[1] //http 協議

result[2] //www.t1amo.com域名

result[3] //about.html路徑

怎麼去除字符串先後的空格:

var str=" hello world ";

  • str.replace(/^\s+|\s+$/,'') //"hello world"
  • str.trim()

手機號碼正則:手機號1開頭,第二位是[3,4,5,7,8],再後面9位(總共11位)

function checkPhone(){ 
    var phone = document.getElementById('phone').value;
    if(!(/^1[34578]\d{9}$/.test(phone))){ 
        alert("手機號碼有誤,請重填");  
        return false; 
    } 
}

 

客戶端存儲

瀏覽器本地存儲?

  1. 在較高版本的瀏覽器中,js提供了sessionstorage和globalstorage
  2. 在HTML5中,提供了localstorage來取代globalstorage

sessionStorage:用於存儲一個會話中的數據,這些數據只有在同一個標籤頁或窗口中才能夠訪問,而且瀏覽器關閉後數據自動刪除。

localStorage:用於持久化的本地存儲數據。瀏覽器關閉後數據不丟失除非主動刪除數據;

區別:

  1. 二者都有同源限制:不一樣站點沒法讀取對方存儲的數據
  2. localstorage同一站點的不一樣頁面能夠共享數據,而sessionStorage不能夠。

web storage和cookie的區別?Cookie、sessionStorage 和 localStrorage?

它們都是爲了實現本地存儲而設計的。

  1. 存儲空間:cookie數據大小不能超過4K,webstorage雖然也有存儲大小的限制,可是比cookie大得多,有5M
  2. 數據是否傳遞:cookie是每請求一個頁面都會發送到服務器,webstorage僅用於本地存儲數據,不會與服務器進行交互。
  3. 數據有效時間:cookie在過時時間一直有效,即便窗口和瀏覽器關閉。localstorage存儲持久數據,瀏覽器關閉後數據不丟失除非主動刪除數據;sessionstorage數據在當前瀏覽器窗口關閉後自動刪除。
  4.  Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie須要前端開發者本身封裝setCookie,getCookie

爲何選擇Web Storage而不是Cookie?

    Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie須要前端開發者本身封裝setCookie,getCookie,在不支持web存儲的瀏覽器中,能夠使用cookie和IE userData來解決兼容性

/*識別出是哪類存儲機制*/
var memory=window.localStorage||
           (window.UserDataStorage&& new UserDataStorage())||
           new cookieStorage();
/*而後在對應的機制中查詢數據*/
var value=memory.getItem("name");

cookie 和session 的區別?

  1. cookie的數據存放在瀏覽器上,session的數據存放在服務器上
  2. cookie不是很安全,別人會分析本地cookie而進行cookie欺騙,所以考慮到安全性應該使用session。
  3. session的數據在必定時間內會存放在服務器上,當訪問增多,會影響服務器性能,所以考慮到服務器性能應該使用cookie。
  4. 單個cookie保存的數據不能超過4k,不少瀏覽器都限制一個站點最多保存20個cookie。

因此通常來講,將重要信息存放在session,不重要的須要保存的數據存放在cookie。

請你談談Cookie的弊端?

cookie雖然在持久保存客戶端數據提供了方便,減輕了服務器的負擔,可是還有不少侷限性:

缺點:

  1. 數量和長度的限制:單個cookie保存的數據不能超過4k(1024*4=4096字節,爲了兼容性通常不能超過4095kb),不少瀏覽器都限制一個站點最多保存20個cookie。
  2. 安全性問題:若是cookie被人攔截了,那麼他將得到全部的session信息
  3. 有些狀態不能保存在客戶端。好比爲了防止重複提交表單,須要在服務器端保存一個計數器。若是放在客戶端不會起做用。

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

使用cookie須要注意的問題:

  1. 能夠經過良好的編程來控制保存在cookie中的session對象的大小
  2. 經過加密和安全傳輸技術減少cookie被破解的可能性
  3. 不在cookie中存放重要信息。
  4. 控制cookie的有效期,偷盜者可能拿到一個過時的cookie

cookie的讀取,set,以及刪除?

  1. cookie有名值對組成,以分號和空格隔開。document.cookie="name=value; max-age=xx; path=xx; "
  2. cookie的名值對不容許包含分號,逗號和空白符,要採用全局函數encodeURIComponent()對值進行編碼,讀取的時候用dncodeURIComponent()解碼

cookie屬性:有效期和做用域

  1. 有效期:cookie的默認有效期很短,一旦瀏覽器關閉,數據丟失,若是想延長cookie的有效期,能夠經過設置cookie的max-age屬性(單位是s)
  2. 做用域:cookie的做用域是經過文檔源和文檔路徑肯定的,能夠經過path和domain屬性來配置。cookie是對建立cookie的那個web頁面和該web頁面同目錄或者同目錄的子目錄是可見的。對其餘目錄的頁面是不可見的。

一、cookie設置

function setCookie(name,value,daystoLive,path,domain,secure){
    var cookie=name+"="+encodeURIComponent(value);
    if (typeof daystoLive === "number") cookie+="; max-age="+(daystoLive*24*60*60);
    if (path) cookie+="; ="+path;
    if (domain) cookie+="; domain="+domain;
    document.cookie=cookie;

}

二、cookie的獲取:

function getCookie(){
    var cookie={};
    var all=document.cookie;
    if (all===null) return cookie;
    var list=all.split("; ");
    for (var i = 0; i < list.length; i++) {
        var p=list[i].indexOf("=");
        var name=list[i].substring(0,p);
        var value=list[i].substring(p+1);
        value=decodeURIComponent(value);
        cookie[name]=value;
    }
    return cookie;//返回的是對象的方式
}

三、cookie刪除:

function delCookie(name,path,domain,secure){
    //必需要設置成相同的域和路徑才能夠
    var cval=getCookie().name;
    if (cval!=null) {
        document.cookie=name+"="+cval+ "; max-age=0";
    };
}

如何實現瀏覽器內多個標籤頁之間的通訊?

調用localStorage,cookie等本地存儲方式

localstorage怎麼使用

 localStorage僅僅支持存儲字符串類型的數據,它和JavaScript對象的使用沒什麼區別。須要注意的是,當存儲一個數字時,會把它自動轉化成字符串。當獲取該值時應該使用parseInt()轉換成數字類型

localStorage.x=10;
var x=parseInt(localStorage.x);

localStorage具備setItem("name","value")方法和getItem("name")方法。分別實現數據存儲和獲取數據,調用removeItem("name")方法能夠刪除數據。

localStorage.setItem("x",10);
localStorage.getItem("x");  //"10"
localStorage.removeItem("x")

調用clear()方法能夠刪除全部存儲的數據。

使用length屬性和key()方法,枚舉存入數據的名字;

for (var i = 1; i < localStorage.length; i++) {
    var name=localStorage.key(i);
        console.log(name);
    var value=localStorage.getItem(name);
        console.log(value);
};

如何保持登陸狀態?

  1. 把登陸信息如帳號、密碼等保存在Cookie中,並控制Cookie的有效期,下次訪問時再驗證Cookie中的登陸信息便可。
  2. 保存登陸信息有多種方案。最直接的是把用戶名與密碼都保持到Cookie中,下次訪問時檢查Cookie中的用戶名與密碼,與數據庫比較。這是一種比較危險的選擇,通常不把密碼等重要信息保存到Cookie中。
  3. 還有一種方案是把密碼加密後保存到Cookie中,下次訪問時解密並與數據庫比較。這種方案略微安全一些。若是不但願保存密碼,還能夠把登陸的時間戳保存到Cookie與數據庫中,到時只驗證用戶名與登陸時間戳就能夠了。

若是頁面初始載入的時候把ajax請求返回的數據存在localStorage裏面,而後每次調用的時候去localStorage裏面取數,是否可行。

  1. 不能保證數據的實時性,請求和實時性必然會有一方有所犧牲

前端路由的實現原理

大型框架例如Angular的路由就是經過hash實現的。一個url裏的#號叫hash,也就是所謂的錨點。當咱們點擊一個a標籤時,將href屬性設置爲相應的path,就能夠在不用更新網頁狀況下局部的刷新頁面。

hash的運行機制是:

  1. 將路由更新時須要執行的回調函數存儲在對象中。
  2. 點擊a標籤觸發hash改變
  3. 監聽瀏覽器的hashchange事件,執行當前url對應的回調函數,利用DOM操做更新頁面。

具體的代碼以下:

<ul>
        <li><a href="#/">首頁</a></li>
        <li><a href="#/product">產品頁</a></li>
        <li><a href="#/service">服務頁</a></li>
</ul>
<div id="refreshBox"></div>
<script type="text/javascript">
    function Route() {
        /*存儲hash更新時的回調函數到routes裏*/
        this.routes = {};
        this.curUrl = "";
        /*存儲路由更新時的回調到routes中*/
        this.route = function(path, callback) {
                this.routes[path] = callback;
            }
            /*執行當前的回調函數更新頁面*/
        this.refresh = function() {
                this.curUrl = location.hash.slice(1) || '/'; //獲取當前hash
                this.routes[this.curUrl](); //根據對應的hash執行回調函數
            }
            //監聽瀏覽器 url hash 更新事件。
        this.init = function() {
            window.addEventListener("load", this.refresh.bind(this), false);
            window.addEventListener("hashchange", this.refresh.bind(this), false);
        }
    }
    var box = document.getElementById('refreshBox');
    var R = new Route();
    R.init();
    R.route('/', function() {
        box.style.background = "blue";
        box.innerHTML = "這是首頁";
    });

    R.route('/product', function() {
        box.style.background = "red";
        box.innerHTML = "這是產品頁";
    });

    R.route('/service', function() {
        box.style.background = "yellow";
        box.innerHTML = "這是服務頁";
    });
    </script> 

如何實現跨瀏覽存儲

跨域

說一下什麼是javascript的同源策略?

它是一種安全協議。指一段腳本只能讀取來自同一來源的窗口和文檔的屬性,同一來源指的是端口,域名,協議相同。

爲何要有同源限制?

好比一個黑客將真正的銀行登陸的頁面嵌入到他的頁面,當用戶登陸時它就能夠經過js讀取到你表單的內容。

如何解決跨域問題

一、JSONP/ Jsonp的原理。怎麼去讀取一個script裏面的數據。

因爲同源策略的限制,在js中不能夠使用AJAX跨域請求,但能夠在頁面上引入不一樣域的腳本。jsonp正是利用這個特性來實現的。

JSONP又叫填充式json,它由回調函數和傳入回調函數的json數據組成。

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

<script type="text/javascript">
        function jsonpCallback(result) {
            alert(result.msg);
        }
    </script>
    <script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback"></script>

其中jsonCallback是客戶端註冊的,獲取跨域服務器上的JSON數據後,回調的函數。http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback 這個url是跨域服務器取JSON數據的接口,參數爲回調函數的名字,返回的格式爲:jsonpCallback({msg:'this is json data'}) 。如此就生成了一段js語法的文檔, 傳回客戶端就能夠調用jsonpCallBack函數了.

優勢:簡單易用,兼容性好

缺點:

  1. 只支持get請求,不支持POST請求。
  2. 不容易調試:若是回調函數沒有調入成功沒法檢測出具體緣由
  3. 有可能會出現安全問題:遠程服務器可能注入任何內容,因此必須確保對方安全

二、CORS(跨域資源共享)

它定義了瀏覽器和服務器是如何經過可控的方式來進行跨域通訊的,CORS經過一些列特殊的HTTP頭還實現的,經過HTTP頭信息能夠容許雙方判斷請求應該是成功仍是失敗。

三、經過修改document.domain來跨子域

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

四、使用window.name跨域

一個窗口內全部的頁面共享一個window.name屬性,能夠讀寫。

五、使用HTML5提供的window.postMessage()來跨域傳遞數據。IE8+都支持

我的認爲window.name方法既不復雜也能兼容幾乎全部瀏覽器,因此比較好用。

iframe實現跨越的具體方法?

應用頁面建立iframe,src指向數據頁面;數據頁面把數據附加到window.name上;應用界面監聽iframe的onload事件,在此事件中設置這個iframe的src指向本地域的代理文件;獲取數據後銷燬iframe

AJAX

ajax的內部原理

其核心有JavaScript、XMLHTTPRequest、DOM對象組成,經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用JavaScript來操做DOM而更新頁面。

建立ajax過程

  1. 建立一個新的xhr對象
  2. 使用open方法建立一個新的HTTP請求,包含了請求的方法(GET/POST),URL,是否異步
  3. 建立一個響應http請求變化的函數onreadystatechange函數,每當 readyState 屬性改變時,就會調用該函數。當 readyState 等於 4 且http狀態status爲 200 時,表示響應已就緒
  4. 使用send方法發送http請求。
  5. 獲取異步調用返回的數據, 它是xhr對象的 responseText 或 responseXML 屬性
  6. 使用JavaScript和DOM局部刷新頁面

readyState幾個狀態的含義

存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。

  1. 0:請求未初始化
  2. 1:服務器鏈接已創建
  3. 2:請求已接收
  4. 3:請求處理中
  5. 4:請求已完成,且響應已就緒

原生jquery的ajax實現,具體思路

原生:

//首先檢查瀏覽器是否支持XMLHttpRequest對象。
var xhr;
if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP")
};
var xhr = new XMLHttpRequest();
//能夠向URL添加須要發送的數據
//爲了不獲得緩存的結果能夠向URL添加一個惟一的id
//xhr.open("GET","demo_get.asp?t=" + Math.random(),true);
xhr.open("GET", "test.php?key1=value1&key2=value2", true);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var result = xhr.responseText;
    };
}
xhr.send();

jquery:

$.ajax()是最底層的AJAX實現。它包含一個對象參數,以鍵值對的方式提供該方法的請求設置和回調函數。

$.ajax({
    /*發送請求的地址*/
    url: "url",
    /*請求的方式*/
    type: "POST/GET",
    /*是否異步*/
    async: true,
    發送到服務器的數據
    data: {
        name: "furong",
        age: 20
    },
    /*服務器返回數據類型*/
    dataType: "json/html/xml/text/jsonp/script",
    /*請求成功後的回調函數*/
    success: function(data, status, xhr) {
        //..callback
    },
    /*請求失敗時的回調函數*/
    error: function() {
        //error
    }
});

同步和異步的區別

同步:js代碼加載到當前AJAX的時候,頁面裏全部的代碼都會中止加載,當AJAX執行完畢後纔會執行ajax後面的代碼,頁面會出現假死狀態。

異步:當ajax發送請求,等待服務器端返回數據的這個過程中,前臺會繼續執行ajax後面的代碼,也就是說這時候是兩個線程(ajax發送的線程和ajax塊後的線程)                

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

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

ajax的優缺點和在IE下的問題?

優勢:

  1. 不須要插件支持,能夠被大多數瀏覽器支持
  2. 能在不刷新整個頁面的前提下更新數據,提高用戶體驗
  3. A減輕服務器和帶寬的負擔

缺點:

  1. 不支持後退按鈕
  2. 對搜索引擎不友好
  3. 開發和調試工具匱乏
  4. 安全問題,AJAX暴露了與服務器交互的細節。

IE緩存問題:在IE下,若是是GET請求,而且URL不變,這個結果會被緩存

解決辦法:能夠向URL添加一個惟一的id 

xhr.open("GET","demo_get.asp?t=" + Math.random(),true);  

ajax請求的時候get 和post方式的區別?

  1. GET從服務器獲取數據,POST向服務器發送數據
  2. GET使用url傳遞參數,對傳遞數據的類型(ASCII編碼)和長度(2kb)有限制,POST沒有限制。
  3. GET安全性較差,由於發送的數據在url中,是可見的。POST更加安全,由於它是經過http post機制傳值,是不可見的。

什麼狀況下分別使用GET和POST?

POST:

  1. 沒法使用緩存文件(更新服務器上的文件或數據庫)
  2. 向服務器發送大量數據(POST 沒有數據量限制)
  3. 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

GET:

  1. 請求是爲了查找資源,HTML表單數據僅用來幫助搜索。
  2. 請求的數據不超過2kb

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

請求實體

ajax請求時,如何解釋json數據

原生js的AJAX:

  1. eval( '('+jsonstr+')' ) :這種方法不推薦,這種方法解析的時候不會去判斷字符串是否合法,並且json對象中的js方法也會被執行,這是很是危險的。
  2. JSON.parse(jsonstr):解析JSON格式的字符串,返回一個js值,若是字符串不合法會報錯。

Jquery的AJAX:

jquery異步請求將type設爲「json」,若是不添加該條屬性,則返回來的爲字符串。或者利用$.getJSON()方法得到服務器返回json數據,這時候返回的就是json對象了

$.each()是用來在回調函數中解析JSON數據的方法

$.each( collection, callback(indexInArray, valueOfElement) )

success : function(data) {
      $.each(data.list,function(index,item){
       alert(item.id);
      })
     }

多個ajax怎麼處理

Ajax 同時處理多個異步請求,可能出現這樣的錯誤:只有最後一個異步請求有效,其餘的都沒效果。因此當咱們執行完一次異步請求就應該把此次建立出來的 XMLHttpRequest 對象刪除,而後再執行下一次異步請求。刪除使用 delete 便可:delete xhr;  

<body>
    <p>Input1:<input type="text" id="first" /> <span id="firstSpan"></span></p>
    <p>Input2:<input type="text" id="second" /> <span id="secondSpan"></span></p>
    <p>Input3:<input type="text" id="three" /> <span id="threeSpan"></span></p>
    <p><input type="button" value="發送" onclick="test();" /></p>
</body>
</html>
<script language="javascript">
    function getData(url, input, label) {
        var xhr;
        if (window.ActiveXObject) {
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        } else if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        }
        var val = document.getElementById(input).value;
        var realUrl = url + "?time=" + new Date().getTime() + "&text=" + val;
//GET請求查詢字符串必須進行編碼。並且全部的鍵值對必須&分割 realUrl
= encodeURI(encodeURI(realUrl)); xhr.onreadystatechange = function() { if (xhr.readyState==4 && xmlHttp.status==200) { var labelSpan = document.getElementById(label); labelSpan.innerHTML = decodeURI(xhr.responseText); delete xhr; // 手動刪除 xhr = null } } xmlHttp.open('GET', realUrl); xmlHttp.send(null); } function test() { getData('index.php', 'first', 'firstSpan'); getData('index.php', 'second', 'secondSpan'); getData('index.php', 'three', 'threeSpan'); } </script>
<?php
    header('Content-Type:text/html;Charset=utf-8');
    echo $_GET['text'];
?>

JSON

JSON 的瞭解?

  1. JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。
  2. 它是基於JavaScript的一個子集。數據格式簡單, 易於讀寫, 佔用帶寬小,是先後臺數據交互最多見的一種形式。
  3. 格式採用鍵值對的方式,{'age':'12', 'name':'back'}

XML和JSON的區別?

  1. 數據體積方面:json比xml數據體積小
  2. 數據交互方面:json與JavaScript的交互更加方便,更容易解析處理
  3. 數據描述方面:json比xml要差
  4. 傳輸速度方面:json比xml快的多

JSON字符串轉換爲JSON對象(互轉)

  1. eval( '('+jsonstr+')' ) :這種方法不推薦,該方法解析的時候不會去判斷字符串是否合法。eval會執行json串中的表達式, 這種方式不安全
  2. JSON.parse(jsonstr):解析JSON格式的字符串,返回一個js值,若是字符串不合法會報錯。 
  3. jQuery支持的轉換方式:$.parseJSON( jsonstr );
  4. JSON.stringify(jsonobj); //能夠將json對象轉換成json字符串

瀏覽器、http

一個頁面從輸入 URL 到頁面加載顯示完成,這個過程當中都發生了什麼?(流程說的越詳細越好)

  1. 用戶發送一個url請求
  2. 瀏覽器經過DNS獲取網站的IP地址:客戶端先檢查本地是否有對應的IP地址,若找到則返回,若沒有則請求上級DNS服務器,直到找到或找到根節點。
  3. 瀏覽器和服務器經過TCP三次握手來創建TCP鏈接。
  4. 一旦鏈接創建,瀏覽器會經過該鏈接向服務器端發送HTTP請求
  5. 遠程服務器找到資源並返回響應報文,響應報文中包含狀態碼。(200表示請求成功)
  6. 請求成功後服務器返回相應的資源,客戶端下載資源
  7. 釋放TCP鏈接。
  8. 接下來就是頁面渲染階段了。首先解析HTML生成DOM樹,再解析CSS文件生產渲染樹。 javascript又能夠根據 DOM API 操做 DOM

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

一、三次握手:爲了將數據準確無誤的送達目標處,TCP協議採用三次握手策略。

三次握手的過程是:

  1. 發送端先發送一個帶有SYN標誌的數據包給接收端
  2. 接收端收到數據包後,傳回一個帶有SYN/ACK標誌的數據包以示傳達確認信息
  3. 發送端再發送一個帶有ACK表示的數據包以示握手成功。

在這個過程中,若是發送方在規定的延遲時間內沒有收到回覆則默認接收方沒有收到請求,TCP協議會再次發送數據包。直到收到回覆爲止。

二、斷開一個TCP鏈接須要四次握手:

  1. 主動關閉方發送一個FIN,用來關閉主動方到被動方的數據傳送。(可是在fin包以前發送出去的數據,若是沒有收到ack確認報文,主動關閉方仍是會再次發送這些數據。此時主動關閉方還能夠接受數據)
  2. 被動關閉方收到fin包後,發送一個ack給對方。確認序號爲收到序號+1。
  3. 被動關閉方發送一個fin,用來關閉被動關閉方到主動關閉方的數據傳送。
  4. 主動關閉方收到fin後,發送一個ack給對方,確認序號爲收到序號+1,至此,完成四次握手。

其餘 HTTP 請求方法

在請求頭的第一行包含了請求的方法,它包括OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE

  1. GET:從指定資源請求數據
  2. POST:向指定的資源發送數據
  3. HEAD:和GET相同,可是隻返回HTTP報頭,不返回文檔主體
  4. DELETE:刪除指定資源
  5. OPTIONS:返回服務器支持的HTTP方法
  6. CONNECT:把請求的鏈接轉換到透明的TCP/IP通訊
  7. PUT:上傳指定的URL表示

TCP和UDP的區別

  1. TCP(Transmission Control Protocol,傳輸控制協議):是基於鏈接的協議。也就是說在發送數據前,必須和對方創建可靠的鏈接。一個TCP鏈接必須經過三次握手才能創建起來。
  2. UDP(User Data Protocol,用戶數據報協議):是於TCP相對應的協議。它是面向非鏈接的協議。也就是說他不與對方創建鏈接,而是直接把數據包發送過去。UDP適用於一次只傳少許的數據、而且對可靠性要求不高的應用環境

HTTP狀態碼

  1. 200 OK 請求成功
  2. 201 Created 請求成功而且服務器建立了新的資源
  3. 202 Accepted 請求接受但還沒有處理
  4. 301 Move Permanently 永久性重定向,請求的網頁已被永久性的移到了新的位置。請求的報文中會附帶重定向的URL。
  5. 302 Found 臨時性重定向
  6. 304 Not Modified 自從上次請求後,請求的網頁未修改過。可直接使用緩存
  7. 400  Bad Request 服務器沒法理解請求的格式
  8. 401 Unauthorized 請求未受權。
  9. 402 Forbidden 禁止訪問。
  10. 404 Not Found 找不到如何與 URI 相匹配的資源。
  11. 500 Internal Server Error 最多見的服務器端錯誤。
  12. 503 Service Unavailable 服務器端暫時沒法處理請求(多是過載或維護)。

HTTP最多見的響應頭

  1. Allow 服務器支持哪些請求方法(如GET、POST等);
  2. Content-Encoding 數據的壓縮格式
  3. Content-Length 表示內容長度
  4. Content-Type 數據的類型.
  5. Cache-controll 它是一個相對時間,表示從請求時間到過時時間的秒數。
  6. Date:當前的GMT時間。
  7. ETag:Last-Modified相似, 不過他發送的是一個字符串來標識url的版本
  8. Expires 它是一個絕對時間,表示在指定時間後緩存失效。-1或0則是不緩存. 
  9. Last-Modified 當前資源的最後修改時間,客戶能夠經過If-Modified-Since請求頭提供一個日期,只有改動時間遲於指定時間的文檔纔會返回,不然返回一個304狀態
  10. Location 配合302狀態碼(臨時性重定向)使用, 用於告訴客戶找誰
  11. Server 服務器的類型

http請求頭有哪些字段

  1. 請求行:請求的方法,url,http協議版本( url在請求行, cookie在請求頭)
  2. Accept-Encoding 客戶端支持的數據壓縮格式
  3. Accept-Language 客戶端的語言環境
  4. Connection:處理完此次請求後是否斷開鏈接仍是繼續保持鏈接
  5. Cache-Control 指定請求和響應遵循的緩存機制
  6. pragma:no-cache表示禁用緩存,必須返回一個刷新後的文檔

HTTP和HTTPS

  1. HTTP協議一般在TCP協議之上
  2. 在HTTP和TCP之間添加一個安全協議層,這個時候就成了HTTPS
  3. http端口號80,https是443。http更加安全

http的端口號,ftp的端口號

  1. HTTP默認的端口號爲80
  2. FTP默認的端口號爲21
  3. HTTPS默認的端口號爲443

爲何HTTPS安全

  1. 由於網絡請求須要中間有不少的服務器路由器的轉發。中間的節點均可能篡改信息
  2. 而使用HTTPS,密鑰只有在你和終點站纔有。
  3. 之因此比較安全是由於它利用SSL/TSL協議傳輸,保證了數據傳輸過程的安全。

關於Http 2.0 你知道多少?、http1和http2的區別

  1. http2採用二進制格式而非文本格式
  2. http2使用爆頭壓縮,下降了開銷
  3. 讓服務器能夠將響應主動推送到客戶端的緩存中
  4. http2是徹底的多路複用,非有序並阻塞的。只須要一個鏈接便可實現並行。

什麼是Etag?應用

  1. 服務器使用它來判斷頁面是否被修改過。
  2. 當瀏覽器請求一個頁面,服務器返回頁面而且給頁面加上一個Etag,瀏覽器緩存頁面和Etag,再次請求該頁面時將Etag發送給服務器,服務器檢查Etag判斷未修改,返回304和空的響應體。瀏覽器收到304的狀態碼後使用緩存文件。

web緩存,瀏覽器怎麼知道要從緩存獲取;

  1. 當瀏覽器請求一個頁面,服務器返回頁面而且給頁面加上一個Etag,瀏覽器緩存頁面和Etag,再次請求該頁面時將Etag發送給服務器,服務器檢查Etag判斷未修改,返回304和空的響應體。瀏覽器收到304的狀態碼後使用緩存文件。

有沒有方法不請求不通過服務器直接使用緩存。(強緩存和協商緩存的命中和管理)、瀏覽器緩存的區別

  1. 瀏覽器在加載資源時,首先瀏覽器會根據第一次請求資源時緩存的響應頭裏的Expires和Cache-Control信息來判斷是否命中強緩存,若是命中,瀏覽器直接從緩存中讀取資源,不會發送請求到服務器。
  2. 當強緩存沒有命中的時候,瀏覽器發送一個請求到服務器。服務器根據響應頭的Last-Modified和Etag信息來判斷是否命中協商緩存,若是命中,服務器返回一個304的狀態碼和空的響應體,瀏覽器收到304的狀態碼後使用緩存文件。
  3. 當協商緩存沒有命中的時候,瀏覽器直接從服務器加載資源。

Expires和Cache-Control

Expires和Cache-Control是http響應頭信息,都用來表示資源在客戶端緩存的有效期。瀏覽器強緩存就是利用它們來實現的。

Expires是較老的強緩存管理header,它是服務器返回的一個絕對時間。用GMT格式的字符串表示。它的緩存原理是:

  1. 當瀏覽器第一次請求一個資源時,服務器返回資源的同時,會在響應頭裏加上Expires的header。
  2. 瀏覽器收到這個資源後,會把資源和響應頭都緩存下來。
  3. 當瀏覽器再次請求這個資源時,先在本身的緩存裏尋找,找到後判斷當前請求時間是否在Expires以前。若是是就命中強緩存,瀏覽器直接從緩存中讀取資源,不會發送請求到服務器。
  4. 若是緩存都沒有命中,瀏覽器直接從服務器加載資源時,Expires會被更新。

Cache-Control是比較新的緩存管理header,它是一個相對時間,單位是秒,它的緩存原理是:

  1. 當瀏覽器第一次請求一個資源時,服務器返回資源的同時,會在響應頭裏加上Cache-Control的header。
  2. 瀏覽器收到這個資源後,會把資源和響應頭都緩存下來。
  3. 當瀏覽器再次請求這個資源時,先在本身的緩存裏尋找,找到後根據第一次請求時間和Cache-Control設定的有效期,計算出一個資源過時時間。若是當前請求事情在過時時間以前。若是是就命中強緩存,瀏覽器直接從緩存中讀取資源,不會發送請求到服務器。
  4. 若是緩存都沒有命中,瀏覽器直接從服務器加載資源時,Cache-Contro會被更新。

304與200讀取緩存的區別?講講304緩存的原理

  1. 當瀏覽器對某個資源的請求命中了強緩存時,返回的http狀態爲200
  2. 當瀏覽器對某個資源的請求沒有命中強緩存,就會發一個請求到服務器,驗證協商緩存是否命中,若是協商緩存命中,請求響應返回的http狀態爲304,瀏覽器收到304的狀態碼後使用緩存文件。

禁止緩存,期限,修改/請列舉三種禁止瀏覽器緩存的頭字段, 並寫出相應的設置值

1.加載文件的時候在文件末尾給一個時間戳做爲版本參數以強制刷新

<script>
    var js = document.createElement("script");
    js.src = "test.js?random" + Math.random(); document.body.appendChild(js); </script>

2.meta方法:在meta標籤裏設置http-equiv屬性,它是用來在HTML文檔中模擬HTTP響應頭報文的東西。

  1. expires: 告訴瀏覽器把回送的資源緩存多長時間  -1或0則是不緩存
  2. Cache-Control: no-cache 描述的是相對時間。  
  3. Pragma: no-cache 設定禁止瀏覽器從本地獲取緩存。
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">

在css/js代碼上線以後開發人員常常會優化性能,從用戶刷新網頁開始,一次js請求通常狀況下有哪些地方會有緩存處理?

dns緩存,cdn緩存,瀏覽器緩存,服務器緩存。

webscoket會用嗎?webSocket如何兼容低瀏覽器,websocket原理,應用場景

一、webscoket是HTML5提供的傳輸協議。websocket是應用層第七層上的一個應用層協議,它必須依賴 HTTP 協議進行一次握手 ,握手成功後,數據就直接從 TCP 通道傳輸,與 HTTP 無關了。它能夠將服務器的更新及時主動的發給客戶端,而不須要客戶端以必定時間間隔去輪詢。

二、目前主流的瀏覽器都支持這個協議,IE還不支持。如何兼容呢?

Adobe Flash Socket 、 ActiveX HTMLFile (IE) 、 基於 multipart 編碼發送 XHR 、 基於長輪詢的 XHR

三、原理:Websocket的數據傳輸是frame形式傳輸的,好比會將一條消息分爲幾個frame,按照前後順序傳輸出去。這樣作會有幾個好處:

  1. 大數據的傳輸能夠分片傳輸,不用考慮到數據大小致使的長度標誌位不足夠的狀況。
  2. 和http的chunk同樣,能夠邊生成數據邊傳遞消息,即提升傳輸效率。

四、應用場景:社交聊天、彈幕、多玩家遊戲、協同編輯、基於位置的應用、體育實況更新、視頻會議/聊天等須要高實時的場景

說說網絡分層裏七層模型是哪七層(從上到下)

  1. 應用層:容許訪問OSI環境的手段
  2. 表示層:對數據進行翻譯、加密和壓縮
  3. 會話層:創建、管理和終止會話
  4. 傳輸層(TCP和UDP):提供端到端的可靠報文傳遞和錯誤恢復
  5. 網絡層(IP):負責數據包從源到宿的傳遞和網際互連
  6. 數據鏈路層:將比特組裝成幀和點到點的傳遞
  7. 物理層:經過媒介傳輸比特,肯定機械及電氣規範

各類協議

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

介紹一下你對瀏覽器內核的理解?

主要分爲渲染引擎和JS引擎,瀏覽器內核不一樣致使渲染的效果不一樣。

  1. 渲染引擎:負責取得網頁的內容(HTML、圖片,css等),以及計算網頁的顯示方式,再輸出到顯示器或打印機
  2. JS引擎:解析和執行JavaScript來實現網頁的動態效果。

介紹經常使用的幾種瀏覽器和內核

  1. IE:Trident 
  2. Firefox:Gecko
  3. Opera:之前是presto內核,Opera現已改用Google Chrome的Blink內核
  4. chrome:Blink(基於webkit,Google與Opera Software共同開發) 
  5. safari:WebKit

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

  1. 基於 AJAX 的長輪詢(long-polling)方式,服務器Hold一段時間後再返回信息;
  2. HTTP Streaming,經過iframe和<script>標籤完成數據的傳輸;
  3. TCP 長鏈接
  4. HTML5新引入的WebSocket,能夠實現服務器主動發送數據至網頁端

上述的1和2統稱爲comet技術

線程與進程的區別

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

性能優化

漸進加強和優雅降級

  1. 漸進加強:先針對低版本的瀏覽器構建頁面,保證最基本的功能後咋針對高版本的瀏覽器進行效果、交互等方面的改進,以提高用戶體驗。
  2. 優雅降級:一開始就構建完整的功能,而後在針對低版本的瀏覽器進行兼容。

網站打開比較卡,你怎麼優化;

優化網站代碼,對網站進行重構。

你有哪些性能優化的方法?

  1. 代碼層面:避免使用css表達式,避免使用高級選擇器,通配選擇器,避免寫行內樣式。少用全局變量,用innerHTML代替DOM操做,減小DOM操做次數,緩存DOM節點查找的結果,避免全局查詢,多個變量聲明合併,避免圖片和iFrame等的空Src。空Src會從新加載當前頁面,影響速度和效率,
  2. 緩存利用:緩存Ajax,多個域名緩存,使用CDN,使用外部js和css文件以便緩存,添加Expires頭,服務端配置Etag等等
  3. 減少請求數量:合併樣式和腳本,使用css sprite,圖片按需加載,靜態資源延遲加載。
  4. 減小帶寬:壓縮文件,開啓GZIP

爲何利用多個域名來存儲網站資源會更有效?

網站資源指網站的圖片、視頻、js、css。服務器直接把相應文件發送到客戶端的文件都是靜態資源。(動態資源通常指數據庫資源)。

  1. 使CDN緩存更方便:靜態資源和動態資源分服務器存放,使用不一樣的服務器處理請求。
  2. 突破瀏覽器的併發限制。比較老的瀏覽器(IE6)只有兩個併發,現代瀏覽器是6個併發。併發請求只針對同一個域名的,即同一時間針對同一域名下的請求數量有限制,超過限制的資源會阻塞。
  3. 節省cookie帶寬:每請求一個頁面都會發送一次主域名下的cookie,請求頭的cookie不能壓縮,若是cookie較多時,會形成發送的數據過大,致使速度變慢。使用其餘域名來保存cookie
  4. 節約主域名的鏈接數,優化頁面響應速度
  5. 防止沒必要要的安全問題。(上傳js竊取主站cookie)

關於多域名,也不是越多越好,瀏覽器作dns解釋也是耗時間的,因此控制在2~4個之間。

移動端性能優化

  1. 儘可能使用css3動畫,開啓硬件加速。
  2. 適當使用touch事件代替click事件。
  3. 避免使用css3漸變陰影效果。
  4. 能夠用transform: translateZ(0)來開啓硬件加速。
  5. 不濫用Float。Float在渲染時計算量比較大,儘可能減小使用
  6. 不濫用Web字體。Web字體須要下載,解析,重繪當前頁面,儘可能減小使用。
  7. 合理使用requestAnimationFrame動畫代替setTimeout
  8. CSS中的屬性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)會觸發GPU渲染,請合理使用。過渡使用會引起手機過耗電增長
  9. PC端的在移動端一樣適用

談談你對重構的理解

網站重構也就是說是在不改變UI的狀況下,對網站進行優化,簡化結構、添加可讀性。

對於傳統的網站來講重構一般是:

  1. 表格(table)佈局改成DIV+CSS
  2. 使網站前端兼容於現代瀏覽器
  3. 對於移動平臺的優化
  4. 針對於SEO進行優化

深層次的網站重構應該考慮的方面:

  1. 減小代碼間的耦合
  2. 讓代碼保持彈性
  3. 嚴格按規範編寫代碼
  4. 設計可擴展的API
  5. 代替舊有的框架、語言(如VB)
  6. 加強用戶體驗

一般來講對於速度的優化也包含在重構中:

  1. 壓縮JS、CSS、image等前端資源
  2. 程序的性能優化(如數據讀寫)
  3. 採用CDN來加速資源加載
  4. 對於JS DOM的優化
  5. HTTP服務器的文件緩存

什麼樣的前端代碼是好的

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

CDN,爲何cdn比較快;

CDN:內容分發網絡,由於他讓用戶就近取得所需內容,能夠使內容傳輸的更快,提升用戶訪問網站的速度。

怎樣減小http請求次數

  1. CSS Sprites
  2. 合併js,css文件
  3. js,css,images等資源的壓縮
  4. CDN託管
  5. 緩存的使用

上線後,如何監控網站

能夠使用一些監控工具,好比監控寶等等,若是訪問不了,監控工具就會按照你設置的方式給你提醒。這個時候你就能夠立刻知道問題並想辦法解決。不用本身常常去手動訪問嘗試了。

打不開網站,什麼緣由形成的,解決辦法

  1. 服務器/空間不穩定:找個穩定的服務器很重要
  2. IP被限制了:換個ip訪問;或者使用代理服務器假裝訪問
  3. 通訊異常:重啓電腦,或者路由設備
  4. 本地DNS緩存:更新DNS。能夠選擇電腦自動更新,也能夠手動清空緩存:ipconfig /displaydns ,ipconfig /flushdns,清空DNS緩存
  5. 網站的域名或者空間到期:及時續費

你如何對網站的文件和資源進行優化?

  1. 文件合併
  2. 文件壓縮
  3. 使用CDN託管
  4. 使用多個域名來緩存資源

你都使用哪些工具來測試代碼的性能?

  1. Profiler
  2. JSPerf
  3. Dromaeo

一個頁面上有大量的圖片(大型電商網站),加載很慢,你有哪些方法優化這些圖片的加載,給用戶更好的體驗。

  1. 圖片懶加載,在頁面的未可視區域添加一個滾動條事件,判斷圖片位置和瀏覽器頂端的距離與頁面的距離,若是前者小於後者,優先加載。
  2. 若是爲幻燈片,相冊等,能夠使用圖片預加載技術,將當前展現圖片的前一張和後一張優先下載
  3. 若是圖片爲css圖片,能夠使用css sprite ,iconfont等技術
  4. 若是圖片過大,能夠使用特殊編碼的圖片,加載時會先加載一張壓縮的特別厲害的縮略圖,以提升用戶體驗。
  5. 若是圖片展現區域小於圖片的真實大小,則因在服務器端先進行圖片壓縮,圖片壓縮後大小與展現一致。

談談之前端角度出發作好SEO須要考慮什麼?

  1. 瞭解搜索引擎如何抓取網頁和如何索引網頁:須要知道一些搜索引擎的基本工做原理,各個搜索引擎之間的區別,搜索機器人如何進行工做,搜索引擎如何對搜索結果進行排序等等
  2. Meta標籤優化:主要包括主題,網站描述,和關鍵詞。還有一些其它的隱藏文字好比Author(做者),Category(目錄),Language(編碼語種)等
  3. 如何選取關鍵詞並在網頁中放置關鍵詞:首先要給網站肯定主關鍵詞(通常在5個上下),而後針對這些關鍵詞進行優化,包括關鍵詞密度,相關度,突出性等等
  4. 瞭解主要的搜索引擎:雖然搜索引擎有不少,可是對網站流量起決定做用的就那麼幾個。好比英文的主要有Google,Yahoo,Bing等;中文的有百度,搜狗,有道等。不一樣的搜索引擎對頁面的抓取和索引、排序的規則都不同。還要了解各搜索門戶和搜索引擎之間的關係
  5. 主要的互聯網目錄:網站目錄和搜索引擎的主要區別是網站內容的收集方式不一樣。目錄是人工編輯的,主要收錄網站主頁;搜索引擎是自動收集的,除了主頁外還抓取大量的內容頁面。
  6. 按點擊付費的搜索引擎:能夠經過搜索引擎的點擊廣告來定位商業網站,這裏面也大有優化和排名的學問,學會用最少的廣告投入得到最多的點擊。
  7. 搜索引擎登陸:網站作完了之後,要讓別人找到你,最簡單的辦法就是將網站提交到搜索引擎。
  8. 連接交換和連接普遍度:其它網站到你的網站的連接越多,你也就會得到更多的訪問量。更重要的是,你的網站的外部連接數越多,會被搜索引擎認爲它的重要性越大,從而給你更高的排名。
  9. 合理的標籤使用 

你日常寫CSS的時候有考慮過CSS的性能麼

  1. 避免使用css表達式,表達式會進行繁瑣的求值,當改變頁面(滾動,改變窗口大小)都會進行求值,影響瀏覽器的性能。
  2. 避免使用統配選擇器*,由於它將全部的標籤都初始化了,很佔用資源。
  3. 儘可能不要使用太小的圖片作背景的平鋪,假如須要1*1px平鋪100*100px須要10000次,也很佔用資源。
  4. 儘可能合寫css,能夠減小css的字節
  5. 避免使用高級選擇器,使用單一的或者儘可能少的class來解決。
  6. 學會利用繼承,在css裏不少屬性能夠繼承,好比visibility,font-family等等

reflow和repaint(重排和重繪)

1.repaint(重繪):改變DOM元素的視覺效果時會觸發,使瀏覽器變慢,由於改變某個元素的視覺效果會check這個DOM元素內的全部節點,會從新對DOM渲染。

  好比:opacity、background-color、visibility、outline

2.reflow(迴流):改變DOM元素的位置時會觸發,比repaint開銷更大,由於他會從新計算全部元素的位置和佔用的面積,這樣會引發整個頁面的從新渲染,他也會觸發repaint。(display:none的元素不會引起重排和重繪)

  好比:js添加刪除元素,用js改變DOM的可見性(display:none-block),添加刪除或改變CSS樣式,增長或移除樣式表,css3的動畫和過渡,使用offsetwidth和offsetheight。還有用戶的一些操做:拖動窗口大小,表單輸入值 ,改變字體大小,更換樣式表等等

常見web安全及防禦原理

1.CSRF(Cross-site request forgery):跨站請求僞造:攻擊者盜用了你的身份,以你的名義發送惡意請求。

CSRF可以作的事情包括:以你名義發送郵件,發消息,盜取你的帳號,甚至於購買商品,虛擬貨幣轉帳......形成的問題包括:我的隱私泄露以及財產安全。

  1. 檢查報頭中的Referer參數確保請求發自正確的網站(但XHR請求可調用setRequestHeader方法來修改Referer報頭);
  2. 對於任何重要的請求都須要從新驗證用戶的身份;
  3. 建立一個惟一的令牌(Token),將其存在服務端的session中及客戶端的cookie中,對任何請求,都檢查兩者是否一致。

2.xss  (Cross Site Scripting):跨站腳本攻擊:經過插入惡意腳本,實現對用戶遊覽器的控制

  1. 瀏覽器自身能夠識別簡單的XSS攻擊字符串,從而阻止簡單的XSS攻擊;
  2. 從根本上說,解決辦法是消除網站的XSS漏洞,這就須要網站開發者運用轉義安全字符等手段,始終把安全放在心上;
  3. 對於普通網民,須要注意儘可能抵擋誘惑,別去點擊非知名網站的連接。

3.sql注入:以SQL語句做爲用戶輸入,從而達到查詢/修改/刪除數據的目的

  1. 永遠不要信任用戶的輸入,要對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度,對單引號和雙"-"進行轉換等。
  2. 永遠不要使用動態拼裝SQL,能夠使用參數化的SQL或者直接使用存儲過程進行數據查詢存取。
  3. 永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。
  4. 不要把機密信息明文存放,請加密或者hash掉密碼和敏感的信息。

哪些地方會出現css阻塞,哪些地方會出現js阻塞?

 CSS 原本是能夠並行下載的,當 CSS 後面跟着嵌入的 JS 的時候,該 CSS 就會出現阻塞後面資源下載的狀況。由於瀏覽器會維持 html 中 css 和 js 的順序,樣式表必須在嵌入的 JS 執行前先加載、解析完。而嵌入的 JS 會阻塞後面的資源加載,因此就會出現上面 CSS 阻塞下載的狀況。

全部瀏覽器在下載 JS 的時候,會阻止一切其餘活動,好比其餘資源的下載,內容的呈現等等。直到 JS 下載、解析、執行完畢後纔開始繼續並行下載其餘資源並呈現內容。

Javascript無阻塞加載具體方式

  1. 把延遲腳本放在頁面底部(body標籤裏)
  2. defer:在script標籤裏設置這個屬性,具備這個屬性的腳本會被延遲到整個頁面都解析完畢後再運行,就是至關於告訴瀏覽器當即下載但延遲執行。
  3. async:它的做用和defer相似,可是腳本不必定會按照前後順序執行。
  4. 動態建立DOM的方式:建立script標籤,插入到DOM中,加載完畢後callBack
  5. 使用jQuery的getScript()方法

兼容性

寫出幾種IE6 BUG的解決方法

常見兼容性問題?

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

超連接訪問事後hover樣式就不出現的問題是什麼?如何解決?

 

Node.JS

瞭解Node麼?Node的使用場景都有哪些?

對Node的優勢和缺點提出了本身的見解?

.如何判斷當前腳本運行在瀏覽器仍是node環境中?

 

框架/項目

你都用過哪些前端框架?爲何選擇這個框架?

博客主要經過Angular這個框架搭建的。

Angualr是一款基於MVC的框架,MVC是模型,視圖,控制器的縮寫。模型負責數據保存,視圖負責用戶界面,控制器負責業務邏輯。

主要應用於單頁面的WEB應用。提供了許多功能,例如雙向數據綁定,AJAX服務,路由,模塊化等。

博客大體過程就是經過視圖,路由等功能搭建了頁面,在控制器裏經過點擊不一樣的連接向AJAX請求服務器端的數據。經過php操做數據庫進行數據庫的查詢,再將返回的數據顯示在視圖上。

在這個過程中也出現了許多問題,例如:在數據傳遞過程中會出現各類各樣的錯誤,這時候就要調試清楚究竟是哪一個環節出了問題。

AngularJS:

它拓展了HTML,提供了豐富的指令。例如

  1. ng-repeat用於每遍歷數組中的一項,就會克隆一次HTML
  2. ng-model把元素值綁定到應用程序
  3. ng-app初始化一個應用程序。

每個ng-controller都有一個做用域,$scope對象擁有屬性和方法,當把scope對象加到控制器時,視圖就能夠獲取這些屬性。

每個應用都有一個rootscope根做用域,也就是說它的屬性和方法能夠做用在app的全部元素當中

Angular還具備http服務,用於讀取遠程服務器上的數據

 $http.get("data/clickRate.php").success(function(response) {
            $scope.clickRate = response;
        });

Angular還提供路由。它主要經過#號來實現,由於url中#號後面的內容會被忽略掉,點擊連接時向服務器請求的地址是相同的。每當點擊鏈接時就會顯示不一樣的內容。

Angular優勢缺點

Angular JS (Angular.JS) 是一組用來開發Web頁面的框架

優勢:

是一個比較完善的MVC框架,包含了模板,雙向數據綁定,路由功能。雙向數據綁定多是AngularJS最酷最實用的特性,將MVC的原理展示地淋漓盡致.

自帶豐富的angular指令,無需進行手工DOM操做。

AngularJS很小,只有60K,兼容主流瀏覽器,與 jQuery 配合良好

缺點:

  1. ng-view只能有一個,不能嵌套多個視圖。
  2. 對於特別複雜的應用場景,性能可能會出現問題。

angular的雙向綁定原理

Angular實現了雙向綁定機制。所謂的雙向綁定,無非是從界面的操做能實時反映到數據,數據的變動能實時展示到界面。

 

 

Bootstrap瞭解程度

對於SASS或是Less的瞭解程度?喜歡那個?

你以爲jQuery或zepto源碼有哪些寫的好的地方

react native是怎麼作到用js調用原生API的?怎麼把js代碼和java或者OC鏈接起來的?介紹底層的實現

如何評價AngularJS和BackboneJS

jquery綁定click的方法有幾種

vue.js雙向綁定的原理,講一講MVVM

jQuery源碼有看過嗎?請說出你印象最深入部分的原理。

請說出jQuery內部判斷數據類型的巧妙方式。

針對 jQuery 的優化方法?

你從jQuery學到了什麼?

Jquery與jQuery UI 有啥區別?在jquery方法和原型上面添加方法的區別和實現($.extend,$.fn.extend),以及jquery對象的實現(return new jQuery.fn.init)

jquery 中如何將數組轉化爲json字符串,而後再轉化回來?

react虛擬DOM爲何有優點,我用原生的爲啥就慢,是什麼緣由;

 

vuejs與angularjs的區別
vuex是用來作什麼的
看過哪些框架的源碼
要是讓你本身寫一個js框架你會用到哪些設計模式,日常在項目中用到過哪些設計模式,說說看
你在項目中創新性地解決了哪些難題?
 

工具

對於前端自動化構建工具備瞭解嗎?簡單介紹一下

你經常使用的開發工具是什麼,爲何?

用過哪些自動化構建工具,怎麼用的

談談你對webpack的見解,webpack底層實現原理,webpack是用來幹嗎的

平時如何管理你的項目?

gulp底層實現原理
gulp與webpack區別
 

新技術

說說最近最流行的一些東西吧?常去哪些網站?

對前端模塊化的認識

ES6的瞭解,es6哪些特性比較吸引你,ES6裏頭的箭頭函數的this對象與其餘的有啥區別

requireJS的原理是什麼? requirejs怎麼防止重複加載

說說你對Promise的理解,構造一個 Promise,用promise手寫ajax

babel是如何將es6代碼編譯成es5的

說說你對AMD和Commonjs的理解

說說你對MVC和MVVM的理解

AMD和CMD 規範的區別

模塊化怎麼作?

如何將項目裏面的全部的require的模塊語法換成import的ES6的語法?

看過那些書(高級程序設計看了幾遍,有啥收穫)

對數據庫的瞭解,mysql與 MongoDB的區別

分別說說同步和異步模塊化的應用場景,說下AMD異步模塊化實現的原理?

一個靜態資源要上線,裏面有各類資源依賴,你如何平穩上線

若是要你去實現一個前端模板引擎,你會怎麼作

手指點擊能夠觸控的屏幕時,是什麼事件?

編程

編寫一個b繼承a的方法;

function A(name){
    this.name = name;
    this.sayHello = function(){alert(this.name+" say Hello!");};
}
function B(name,id){
    A.call(this,name); //在子類型的構造函數內部調用父類型的構造函數      
     this.id = id;  
}
var b=new B("furong",1)
b;//B {name: "furong", id: 1, sayHello: function}

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

原始類型和引用類型克隆的時候有很大區別,由於原始類型存儲的是簡單的數據段,引用類型存儲的是對象在內存當中的地址。

淺克隆:原始類型值傳遞,引用類型引用傳遞。

深克隆:對新對象的修改不會影響到原來的對象。

tips:咱們直接經過普通賦值的方式,就實現了函數的克隆,由於函數的克隆會在內存單獨開闢一塊空間,互不影響。

function isClass(obj){
      return Object.prototype.toString.call(obj).slice(8,-1);
}

function deepClone(obj){
    var type=isClass(obj);
    var result;
    if (type==="Array") {
          result=[];
    }else if(type==="Object"){
          result={};
    }else{
        //除了數組和對象,其餘類型的數據均可以經過簡單賦值進行克隆。
        return obj;
    };
    //對象屬性的遍歷
    for (var key in obj) {
        //繼續判斷屬性的數據類型
        if (isClass(obj[key])=="Object" || isClass(obj[key])=="Array") {
             //若是屬性值的對象,遞歸調用
             result[key]=deepClone(obj[key]);
        } else{
            //若是屬性都是簡單的數據段,直接賦值
           result[key]=obj[key];
        }
    }
    return result;
}

 

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

英文字母字節數=length,一箇中文佔兩個字節,因此咱們須要把中文的個數計算出來

ASCII 字符集的碼值從 0 到 255,表明了字母、數字、標點符號和其餘字符

能夠經過charCodeAt(i)獲取每一個位置的Unicode編碼判斷是否爲中文字符

function getBytes(str){
    var len=str.length;
    var result=len;
    for (var i = 0; i < len; i++) {
        if (str.charCodeAt(i)>255) {
            result++;
        };
    };
    return result;
}

獲取url後面的參數並變爲對象

function getSearchObj(){
    var qs=location.search.length>0?location.search.subString(1):'',
        obj={},
        items=qs.length>0?qs.split('&') : [],
        item=null;
        name='',
        value='',
        i=0;
        len=items.length;
    for (var i = 0; i < len; i++) {
        item=items[i].split('=');
        name=decodeURIComponent(item[0]);
        value=decodeURIComponent(item[1]);
        obj[key]=value? value : undefined;
    }
    return obj;

}

三級菜單的實現,簡單描述下你的實現過程;不用框架

  1. 第一級菜單的ul li標籤
  2. 一級li標籤裏包含文字和第二級ul li標籤
  3. 二級li標籤裏包含文字和第三級ul li標籤
 <ul class="menu">
            <li class="level1">一級菜單
                <ul class="level2">
                    <li class="level2-2">二級菜單1
                        <ul class="level3">
                            <li>1-2-3</li>
                            <li>1-2-3</li>
                            <li>1-2-3</li>
                        </ul>
                    </li>
                    <li class="level2-2">二級菜單1
                        <ul class="level3">
                            <li>2-2-3</li>
                            <li>2-2-3</li>
                            <li>2-2-3</li>
                        </ul>
                    </li>
                    <li class="level2-2">二級菜單1
                        <ul class="level3">
                            <li>3-2-3</li>
                            <li>3-2-3</li>
                            <li>3-2-3</li>
                        </ul>
                    </li>
                </ul>
            </li>
            <li class="level1">一級菜單
                <ul class="level2">
                    <li>二級菜單2</li>
                    <li>二級菜單2</li>
                    <li>二級菜單2</li>
                </ul>
            </li>
            <li class="level1">一級菜單
                <ul class="level2">
                    <li>二級菜單3</li>
                    <li>二級菜單3</li>
                    <li>二級菜單3</li>
                </ul>
            </li>
        </ul>

使二級菜單level2和三級菜單level3的display設置爲none;絕對定位,left設置爲寬度的值;高度爲32px;

在js裏,

  1. 獲取一級菜單的nodelist,二級菜單的nodelist,二級菜單li標籤的list
  2. 給每個一級菜單的li綁定mouseover和out事件,使用閉包,獲取每次的下表,over時對應下標的level2[i]顯示,而且top設置爲i*32px;
  3. 給每一個二級菜單中的li綁定事件,over時對應的level3[i]顯示
window.onload = function() {
        var level1 = document.getElementsByClassName("level1");
        var level2 = document.getElementsByClassName("level2");
        var level20Li = document.getElementsByClassName("level2-2");
        var level30 = document.getElementsByClassName("level3");

        for (var i = 0; i < level1.length; i++) {
            level1[i].onmouseover = (function(i) {
                return function() {

                    level2[i].style.display = "block";
                    level2[i].style.top = (i * 32 + "px");
                }
            })(i);
            level1[i].onmouseout = (function(i) {
                return function() {

                    level2[i].style.display = "none";
                }
            })(i);

        }

        for (var i = 0; i < level20Li.length; i++) {
            level20Li[i].onmouseover = (function(i) {
                return function() {
                   console.log(i);
                    level30[i].style.display = "block";
                    level30[i].style.top = (i * 32 + "px");
                }
            })(i);
            level20Li[i].onmouseout = (function(i) {
                return function() {

                    level30[i].style.display = "none";
                }
            })(i);
        }
    }
    (function() {
        var menu = document.getElementById("menu");

        var level1 = menu.getElementsByClassName("level1");
        var level2 = menu.getElementsByClassName("level2");

        addEvent(level1);
        addEvent(level2);

        function addEvent(objects) {
            var len=objects.length;
            for (var i = 0; i < len; i++) {
                objects[i].onmouseover = function() {
                    var children = this.childNodes;
                    for (var j = 0; j < children.length; j++) {
                        if (children[j].nodeName == "UL") {
                            children[j].style.display = "block";
                        }
                    }
                }
                objects[i].onmouseout = function() {
                    var children = this.childNodes;
                    for (var j = 0; j < children.length; j++) {
                        if (children[j].nodeName == "UL") {
                            children[j].style.display = "none";
                        }
                    }
                }
            }
        }    
    })();

 

一個table,點擊按鈕,實現某一列的刷新,不能採用框架,簡單描述下實現過程

<body>
    <table id="tb" border="1" style="border-collapse: collapse;">
        <thead>
            <tr>
                <th>name</th>
                <th onclick="update(this)">age</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>A</td>
                <td>12</td>
            </tr>
            <tr>
                <td>b</td>
                <td>18</td>
            </tr>
            <tr>
                <td>c</td>
                <td>30</td>
            </tr>
        </tbody>
    </table>
    <script type="text/javascript">
    function update(btn) {
        
            var table = document.getElementById("tb");

            var tbody=table.tBodies[0];

            var getObj = function(table) {
                var arr = [],
                    rows = table.tBodies[0].rows,
                    len = rows.length;
                for (var i = 0; i < len; i++) {
                    var key = rows[i].cells[0].innerHTML;
                    var value=rows[i].cells[1].innerHTML;
                    arr[i]={
                        name:key,
                        age:value
                    }
                }
                return arr;
            }

            var arr=getObj(table);
            arr.sort(function(a,b){
                return b.age-a.age;
            })
             
            tbody.innerHTML="";

            for (var i = 0,len=arr.length; i < len; i++) {
                tbody.insertRow(i);
                tbody.rows[i].innerHTML="<td>"+arr[i].name+"</td><td>"+arr[i].age+"</td>";
            }       
    }
    </script>
</body>

點擊按鈕後把數據存在數組裏,數組元素是對象存放name和age,而後按照age排序,清空tbody後把內容逐次加到列表當中

    window.onload = function() {
        var btn = document.getElementById('age');//獲取要刷新那一行的按鈕
        var tbody = document.getElementsByTagName('tbody')[0];
        var tr = tbody.getElementsByTagName('tr');
        var age = [],//保存哪一行的數據
            result = [];//保存刷新後的值
        for (var i = 0; i < tr.length; i++) {
            var msg = parseInt(tr[i].getElementsByTagName('td')[2].innerHTML);
            var brr = [msg, i]
            age.push(brr);//將每一行的數據和對應的行數保存在二維數組中
        };
        flag = true;//只能點擊一次
        btn.onclick = function() {
            if (flag) {
                age = age.sort();//從小到大排序
                for (var i = 0; i < age.length; i++) {
                    var key = age[i][1];
                    result.push(tr[key]);//將排序後的tr保存起來
                };
                tbody.innerHTML = "";
                for (var i = 0; i < result.length; i++) {
                    tbody.appendChild(result[i]);//更新整個table
                };
                flag = false;
            };
        }

    }

實現一個可拖動的div(要考慮到瀏覽器兼容性)

/*盒子設置寬高,而且相對定位*/
 #box {
        width: 100px;
        height: 100px;
        background-color: red;
        position: relative; 
    }
//肯定窗口大小
var screenheight=document.body.clientHeight   /*混雜模式*/
                 ||document.documentElement.clientHeight /*標準模式*/
                 ||window.innerHeight;  /*移動設備*/
var screenwidth=  document.body.clientWidth   /*混雜模式*/
                  ||document.documentElement.clientWidth /*標準模式*/
                   ||window.innerWidth; 
/*  a) 給須要拖拽的節點綁定mousedown, mousemove, mouseup事件
    b) mousedown事件觸發後, 開始拖拽
    c) mousemove時, 須要經過event.clientX和clientY獲取拖拽位置, 並實時更新位置
    d) mouseup時, 拖拽結束
    e) 須要注意瀏覽器邊界的狀況*/
<body>
    <div id="div" style="width: 100px;height: 100px;background: red;position: absolute;">
    </div>
    <script>
    var div = document.getElementById("div");
    var pageWidth = document.documentElement.clientWidth || document.body.clientWidth || window.innerWidth;
    var pageHeight = document.documentElement.clientHeight || document.body.clientHeight || window.innerHeight;
    div.onmousedown = function(e) {
        var e = e || window.event;
        var a = e.clientX - div.offsetLeft;
        var b = e.clientY - div.offsetTop;

        div.onmousemove = function(e) {
            console.log(this.offsetHeight)
            var c = e.clientX - a;
            var d = e.clientY - b;
            if (c < 0) c = 0;
            if (d < 0) d = 0;
            if (c > pageWidth - this.offsetWidth) c = pageWidth - this.offsetWidth;
            if (d > pageHeight - this.offsetHeight) d = pageHeight - this.offsetHeight;

            this.style.left = c + 'px';
            this.style.top = d + 'px';
        }
        this.onmouseup = function() {
            div.onmousemove = null;
        }
    }

 

讓寫個從幾個li中取下標的閉包代碼

<body>
    <ul>
        <li>0</li>
        <li>1</li>
        <li>2</li>
    </ul>
    <script type="text/javascript">
      window.onload=function(){
          /*方法一:循環:閉包*/
         /*var li=document.getElementsByTagName("li");
         for (var i = 0; i < li.length; i++) {
             li[i].onclick=(function(i){
                 return function(){
                     alert(i);
                 }
             })(i)
         };*/

         //方法二:事件代理
         var ul=document.getElementsByTagName("ul")[0];
         ul.onclick=function(e){
            console.log(e.target.innerHTML)
         }
      }

    </script>
</body>

手寫閉包,繼承,

//閉包內的變量不會被垃圾回收機制回收
function fn(){
    var n=0;
    return function(){
        n++;
        console.log(n);
    }
}
var foo=fn();
foo();//1
foo();//2
foo();//3

手寫事件綁定

var EventUtil={
            addEvent:function(item,type,fn){
               if (item.addEventListener) {
                     item.addEventListener(type,fn,false);
               }else if (item.attachEvent) {
                     item.attachEvent('on'+type,fn)  //IE
               }else{
                     item['on'+type]=fn;
               }
            },
            removeEvent:function(item,type,fn){
                if (item.removeEventListener) {
                     item.removeEventListener(type,fn,false);
               }else if (item.detachEvent) {
                     item.detachEvent('ob'+type,fn)  //IE
               }else{
                     item['on'+type]=null;
               }
            },
            getEvent:function(e){
               return e || window.event;
            },
            getTarget: function(e) {
                var e = this.getEvent(e);
                var target = e.target || e.srcElement;
                if (target.nodeType === 3) {//空白節點
                    target = target.parentNode;
                }
                return target;
            }
        }

手寫一個原生ajax

<body>
    <button id="btn" type="button">AJAX局部刷新</button>
    <div id="result"></div>
    <script type="text/javascript">
        var btn=document.getElementById("btn");
        var result=document.getElementById("result");
        btn.onclick=function(){
            var xhr=null;
            if (window.XMLHttpRequest) {
                xhr=new XMLHttpRequest();
            }else{
                xhr=new ActiveXObject("Microsoft.XMLHTTP")
            }
            xhr.open("GET","url",true);
            xhr.onreadystatechange=function(){//建立一個響應HTTP請求變化的函數
                if (xhr.readyState===4 && xhr.status===200) {
                    //使用JavaScript和DOM局部刷新頁面
                    result.innerHTML=xhr.responseText;
                }
            }
            xhr.send(null);
        }
    </script>

 手寫實現jquery裏面的insertAfter(結合nextSibling和insertBefore來實現)

    <script type="text/javascript">
    window.onload = function() {
        var one = document.getElementById("one");
        var two = document.createElement("div");
        two.innerHTML = "2";
        function insertAfter(two, one) {
            var parent = one.parentNode;
            // 看子元素裏有幾個屬性節點
            var child = parent.childNodes;
            var count = 0;
            for (var i = 0; i < child.length; i++) {
                if (child[i].nodeType === 1) {
                    count++;
                };
            };
            /*若是隻有一個*/
            if (count == 1) {
                parent.appendChild(two);
            } else {
                //判斷下一個節點是元素節點,nodeType=1
                var three = one.nextSibling;
                while (three.nodeType != 1) {
                    three = three.nextSibling;
                };
                parent.insertBefore(two, three);
            }
        }
        insertAfter(two, one);
    }

toggleClass實現 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>toggle</title>
    <style>
    #test {
        width: 400px;
        height: 300px;
        margin: 50px auto;
    }
    .red {
        border: 5px solid red;
    }
    
    .opacity {
        opacity: 0.2;
    }
    
    .yellow {
        background-color: yellow;
    }
    </style>
</head>
<body>
    <div id="test" class="yellow"></div>
    <br/>
    <div style="text-align:center;margin:0 auto">
        <button type="button" onclick="toggleClass('red')">紅色邊框</button>
        <button type="button" onclick="toggleClass('opacity')">內填充</button>
    </div>
    <script type="text/javascript">
    var ele = document.getElementById('test'); //獲得元素
    function toggleClass(newClass) {
        var currentClass = ele.className;//獲取當前樣式
        var arr = [];
        var exist = false;//用變量來標識類是否存在
        if (!currentClass) {//若是當前樣式不存在,直接添加
            ele.className = newClass;
        } else {//若是存在
            arr = currentClass.split(' ');//將樣式存放在數組裏方便判斷裏面是否存在新的樣式
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] == newClass) {//若是發現存在
                    exist = true;//標記爲當前樣式中存在新的樣式
                    ele.className = currentClass.replace(newClass, '').trim();//經過字符串的replace方法去除樣式,在賦值給元素的className                
                    break;//退出循環
                }
            }
            if (!exist) {//若是當前樣式中都不存在新的樣式
                ele.className=currentClass+' '+newClass;//將樣式添加到當前樣式當中
            };
        }
    }
    </script>
</body>
</html>

寫一個通用的事件偵聽器函數?

    window.onload = function() {
        var Event = {
            /*視能力分別使用dom2||IE||dom0方式 來綁定事件*/
            addEvent: function(ele, type, fn) {
                if (ele.addEventListener) {
                    ele.addEventListener(type, fn, false);
                } else if (ele.attachEvent) {
                    ele.attachEvent('on' + type, function() {
                        fn.call(ele);
                    });
                } else {
                    ele['on' + type] = fn;
                }
            },
            removeEvent: function(ele, type, fn) {
                if (ele.removeEventListener) {
                    ele.removeEventListener(type, fn, false);
                } else if (ele.detachEvent) {
                    ele.detachEvent('on' + type, fn);
                } else {
                    ele['on' + type] = null;
                }
            },
            stopProrpgation: function(e) {

                e = this.getEvent(e);
                console.log(e);
                if (e.stopProrpgation) {
                    e.stopProrpgation();
                } else {
                    e.cancleBubble = true;
                }
            },
            preventDefault: function(e) {
                e = this.getEvent(e);
                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }
            },
            getEvent: function(e) {

                return e || window.event;
            },
            getTarget: function(e) {
                var e = this.getEvent(e);
                var target = e.target || e.srcElement;
                if (target.nodeTypr === 3) {
                    target = target.parentNode;
                }
                return target;
            }
        }
        var btn = document.getElementById('btn');

        function handler() {
            /*alert(this.id);*/
            Event.getEvent();
            Event.stopProrpgation();
            Event.preventDefault();
        }
        Event.addEvent(btn, 'click', handler);
        /* Event.removeEvent(btn, 'click', handler);*/
    }

如何獲取UA

用來代表用戶的瀏覽器名稱和版本,操做系統等信息。在每一次HTTP請求中,響應頭部都會包含UA字符串,用於瀏覽器識別和數據統計。在js中能夠用navigator.userAgent屬性來獲取本瀏覽器的UA字符串。UA可讓網頁開發者可以根據不一樣的瀏覽器發送不一樣的顯示內容,爲了不瀏覽器不支持的功能,以得到更好的用戶體驗。例如「Mozilla/1.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101Firefox/4.0.1」,此字符串代表這是一個 Windows 版的使用 Gecko 引擎(火狐瀏覽器內核)的火狐瀏覽器。

<form name="Browser">
    瀏覽器名稱:<input type="text" name="appCodeName" ><br>
    完整的瀏覽器名稱:<input type="text" name="appName" ><br>
    瀏覽器版本:<input type="text" name="appVersion" ><br>
    瀏覽器的用戶代理字符串:<input type="text" name="userAgent" ><br>
    <button type="button" onclick="getUA()">點擊獲取瀏覽器信息</button>
</form>
<script>
    function getUA(){
        document["Browser"][0].value=navigator.appCodeName;
        document["Browser"][1].value=navigator.appName;
        document["Browser"][2].value=navigator.appVersion;
        document["Browser"][3].value=navigator.userAgent;
    }
</script>

字符串匹配,一個字符串子在另外一個字符串中出現的次數 

function getStrNum(subStr,str){
    //RegExp構造函數動態建立正則表達式,RegExp構造函數第一個參數是正則表達式主題部分,
    //第二個參數可選,是正則的修飾符,g表示全局搜索
    var pattern=new RegExp(subStr,'g');//全局匹配的正則對象
    //
    return str.match(pattern).length;
}

將一篇文章的每一個單詞首字母大寫;不改變原有的格式

function tooUpperLetter(str) {
    return str.replace(/\b\w+\b/g, function(word) {
        return word.substring(0, 1).toUpperCase() + word.substring(1);
    })
}

快排實現的原理

function quickSort(arr){
    if (arr.length<=1) return arr;
    var left=[],right=[];
    var num=Math.floor(arr.length/2);//取得中間的數值,將它從數組中刪除
    var value=arr.splice(num,1);
    for (var i = 0; i < arr.length; i++) {
        if (arr[i]<value) {
           left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
 return arguments.callee(left).concat(numValue,arguments.callee(right));
}

請用Css寫一個簡單的幻燈片效果頁面

百度搜索框

手機某一行均分爲四個,不知道尺寸的狀況下

如何本身實現一個alert

三個tab頁面,實現代碼

有沒有寫過插件,用js寫過什麼(而後就是具體描述怎麼實現的)

給你一個url,判斷是不是同一個域名(qq.com)下的

圖片預加載

.js:寫一個遞歸。就是每隔5秒調用一個自身,一共100次。

js輪播實現思路

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

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

說下選擇排序,冒泡排序的實現思路

url去參數的題

手寫一個盒子模型中,獲取盒子內子節點的class樣式

深度遍歷DOM節點 

複雜的酒店預訂table

手寫jsonp的實現

手寫鏈表倒數第K個查找

手寫一個jQuery插件

手寫一個簡單遍歷算法

手寫歸併排

實現兩個數組的排序合併,我一開始先合併再排序,他不樂意,而後我用了相似插入排序的方法

手寫實現一個promise(不會)

手寫實現requireJS模塊實現(想了半天才想到createElement("script"),配合異步來加載,閉包導出)

JS配合DOM實現EChart柱狀圖

 

移動端

有移動端的經驗麼?

移動端適配問題

1) <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />   

 //width=device-width :強制讓文檔的寬度與設備的寬度保持1:1

 // initial-scale=1.0:文檔初始化縮放比例是1:

 //user-scalable=0:不容許用戶點擊屏幕放大瀏覽,   

//maximum-scale=1.0:容許用戶縮放到的最大比例,   

注意:content裏多個屬性的設置必定要用逗號+空格來隔開,若是不規範將不會起做用。

其餘屬性有:width;height; initial-scale; minimum-scale; maximum-scale; user-scalable;

2) <meta name="apple-mobile-web-app-capable" content="yes" />    

 //iPhone私有標籤,它表示:容許全屏模式瀏覽

3) <meta name="apple-mobile-web-app-status-bar-style" content="black" />    

//iPhone私有標籤,它指定的iPhone中safari頂端的狀態條的樣式

4) <meta name="format-detection" content="telephone=no; email=no" />    //不識別郵件和不把數字識別爲電話號碼

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

移動端要注意哪些
適配有去考慮麼,retina屏幕啊?

 

關於前端

你以爲哪些站點前端技術比較好的?或者說你平時怎麼學前端的?看過哪些前端的書

你有什麼規劃?

你所瞭解的前端技術棧有哪些

你有什麼問題要問的麼?前端妹子的發展路線都有哪些?前端技術多而雜,好的學習方法?

移動端和pc差異

 自學經歷

數據結構

解釋平衡二叉樹,以及在數據結構中的應用

平衡二叉樹相關知識

圖論最短路徑算法

數組和鏈表的區別,空間和時間上的優劣,查找和刪除的選擇

快排的時間複雜度和空間複雜度。

常見排序算法的時間複雜度 

數據集A、數據集B大小500GB,電腦內存很小,如何求得AB的差集。

數組和鏈表的區別 

後序遍歷的實現代碼

排序算法總結

棧和隊列

冒泡快排算法思路,複雜度

整型數組全排列問題

virtual dom的實現,diff算法

對模塊化了解嗎?說說有哪些模塊化的庫,有了解過模塊化的發展的歷史嗎?(commonJS,RequireJS,SeaJS)

分別說說同步和異步模塊化的應用場景,說下AMD異步模塊化實現的原理?(看JS設計模式的時候看過同步模塊模式,因此我只答了同步模塊化的實現,可是AMD異步的不會)

如何將項目裏面的全部的require的模塊語法換成import的ES6的語法?

複習數據結構 排序算法從新寫一遍,二分,鏈表的算法,BFS,DFS,圖論最短路徑等算法,之前基礎不錯寫了大量博客, 因此看看本身的博客,複習起來很快

刷前端面經 bind,debounce,once,深淺拷貝等的ployfill

事件委託,JQ鏈式調用實現,原生ajax,函數式,柯里化

常見的跨域方式和原理(主要是jsonp和CORS,記得CORS必定要動手本身寫後端才能理解深入)

前端安全之XSS和CSRF,以及如何防護

ES6部分,let暫時性死區,箭頭函數(this指針,arguments的坑),generator/iterator,promise,阮一峯老師的那本電子書

模塊化歷史以及同步異步原理

webpack 2.0 慕課網上看一個大神的視頻,講的很好

360奇舞團瓜瓜老師的性能優化的視頻,關鍵渲染路徑,網頁渲染過程,資源對渲染的阻塞

根據前幾輪面試暴露的缺點,作了下面的實踐

80行代碼的類工廠,原型鏈繼承面向對象的一個實踐

100行簡單實現AMD異步模塊加載器(JS設計模式這本書上有樣例代碼)

看Vue文檔練手,而後閱讀Vue.js早期源碼,簡單實現MVVM雙向綁定,數組監聽,簡單指令實現

看gayhub上的倉庫的代碼,模仿virtual-dom的實現,diff算法

  • padding百分比是相對於父級寬度仍是自身的寬度
相關文章
相關標籤/搜索