"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

2019前端面試經典(html5+css3+JavaScript)

1,2,3請求行,4請求體,5請求體跨域、JSONP 、CORS、postMessage

跨域概念解釋:當前發起請求的域與該請求指向的資源所在的域不一樣。這裡的域指的是這樣的一個概念:我們認為若協議 + 域名 + 端口號均相同,那麼就是同域。 如下表

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

2019前端面試經典(html5+css3+JavaScript)

1,2,3請求行,4請求體,5請求體跨域、JSONP 、CORS、postMessage

跨域概念解釋:當前發起請求的域與該請求指向的資源所在的域不一樣。這裡的域指的是這樣的一個概念:我們認為若協議 + 域名 + 端口號均相同,那麼就是同域。 如下表

2019前端面試經典(html5+css3+JavaScript)

jsonp實現

原生
<script>
var script = document.createElement('script');
script.type = 'text/javascript';

// 傳參並指定回調執行函數為onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);

// 回調執行函數
function onBack(res) {
alert(JSON.stringify(res));
}
</script>

jquery
$.ajax({
url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 請求方式為jsonp
jsonpCallback: "onBack", // 自定義回調函數名
data: {}
});
vue
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'onBack'
}).then((res) => {
console.log(res);
})
配合的後端node實現,其他服務器語言也可以
const querystring = require('querystring');
const http = require('http');
const server = http.createServer();
server.on('request', function(req, res) {
var params = qs.parse(req.url.split('?')[1]);
var fn = params.callback;

// jsonp返回設置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');

res.end();
});
server.listen('8080');
jsoup缺點只能實現get請求
複製代碼

CORS:跨源資源共享 Cross-Origin Resource Sharing(CORS),通常服務器設置,若帶cookie請求,則前後端都需要設置 後端常見設置 response.setHeader("Access-Control-Allow-Origin", "www.domain1.com"); // 若有端口需寫全(協議+域名+端口),允許那些外源請求 response.setHeader("Access-Control-Allow-Credentials", "true"); //是否需要驗證

前端示例

原生
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端設置是否帶cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');

xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
jquery
$.ajax({
...
xhrFields: {
withCredentials: true // 前端設置是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie
...
});
複製代碼
postMessage(data,origin)方法接受兩個參數
demo
a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向domain2傳送跨域數據
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
};

// 接受domain2返回數據
window.addEventListener('message', function(e) {
alert('data from domain2 ---> ' + e.data);
}, false);
</script>
b.html 與a.html不同源
<script>
// 接收domain1的數據
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);

var data = JSON.parse(e.data);
if (data) {
data.number = 16;

// 處理後再發回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
複製代碼

osi模型

七層結構:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層 tcp ucp屬於傳輸層;http屬於應用層

http2.0 http1

  1. HTTP2.0的基本單位為二進制幀
  2. HTTP2.0中幀具有優先級
  3. HTTP2.0的多路複用( 1次連接)
  4. HTTP2.0壓縮消息頭
  5. HTTP2.0服務端推送
  6. HTTP2.0只適用於HTTPS的場景

Vue相關

生命週期順序

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

2019前端面試經典(html5+css3+JavaScript)

1,2,3請求行,4請求體,5請求體跨域、JSONP 、CORS、postMessage

跨域概念解釋:當前發起請求的域與該請求指向的資源所在的域不一樣。這裡的域指的是這樣的一個概念:我們認為若協議 + 域名 + 端口號均相同,那麼就是同域。 如下表

2019前端面試經典(html5+css3+JavaScript)

jsonp實現

原生
<script>
var script = document.createElement('script');
script.type = 'text/javascript';

// 傳參並指定回調執行函數為onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);

// 回調執行函數
function onBack(res) {
alert(JSON.stringify(res));
}
</script>

jquery
$.ajax({
url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 請求方式為jsonp
jsonpCallback: "onBack", // 自定義回調函數名
data: {}
});
vue
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'onBack'
}).then((res) => {
console.log(res);
})
配合的後端node實現,其他服務器語言也可以
const querystring = require('querystring');
const http = require('http');
const server = http.createServer();
server.on('request', function(req, res) {
var params = qs.parse(req.url.split('?')[1]);
var fn = params.callback;

// jsonp返回設置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');

res.end();
});
server.listen('8080');
jsoup缺點只能實現get請求
複製代碼

CORS:跨源資源共享 Cross-Origin Resource Sharing(CORS),通常服務器設置,若帶cookie請求,則前後端都需要設置 後端常見設置 response.setHeader("Access-Control-Allow-Origin", "www.domain1.com"); // 若有端口需寫全(協議+域名+端口),允許那些外源請求 response.setHeader("Access-Control-Allow-Credentials", "true"); //是否需要驗證

前端示例

原生
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端設置是否帶cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');

xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
jquery
$.ajax({
...
xhrFields: {
withCredentials: true // 前端設置是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie
...
});
複製代碼
postMessage(data,origin)方法接受兩個參數
demo
a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向domain2傳送跨域數據
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
};

// 接受domain2返回數據
window.addEventListener('message', function(e) {
alert('data from domain2 ---> ' + e.data);
}, false);
</script>
b.html 與a.html不同源
<script>
// 接收domain1的數據
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);

var data = JSON.parse(e.data);
if (data) {
data.number = 16;

// 處理後再發回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
複製代碼

osi模型

七層結構:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層 tcp ucp屬於傳輸層;http屬於應用層

http2.0 http1

  1. HTTP2.0的基本單位為二進制幀
  2. HTTP2.0中幀具有優先級
  3. HTTP2.0的多路複用( 1次連接)
  4. HTTP2.0壓縮消息頭
  5. HTTP2.0服務端推送
  6. HTTP2.0只適用於HTTPS的場景

Vue相關

生命週期順序

2019前端面試經典(html5+css3+JavaScript)

組件通信

1.父傳子用props,父用子用ref 子調父用$emit,無關係用Bus

Vuex

組件通信庫,可以避免子組件無法改變props的弊端等 mutations 同步操作, 用於改變狀態 官方不推薦異步 action 執行多個mutaions,官方推薦異步操作 mapState、mapGetters、mapActions使用示例

<template>
<el-dialog :visible.sync="show"></el-dialog>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed:{
//這裡的三點叫做 : 擴展運算符
...mapState({
show:state=>state.dialog.show
}),
}
}
</script>
後兩者類似
複製代碼

VueRouter

定義
var routes = [
{
path:"/one",
component:導入的組件1
},
{
path:"/two",
component:導入的組件2
},
];
// 定義路由組件
var router = new VueRouter({
routes
});
// 定義路由
new Vue({
el:"#box",
router
});
訪問設定的路由後 會將<router-view></router-view>替換成相應的模版
html訪問方式 <router-link to="/one">One</router-link>(類似a標籤)
js訪問方式 this.$router.push('/one');
replace方式 替換當前頁面
攜帶的參數 可以通過this.$route.query.xxxx來獲取
複製代碼

Vue雙向綁定

原理:利用了 Object.defineProperty() 這個方法重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現的。 缺點:雙向數據流是自動管理狀態的, 但是在實際應用中會有很多不得不手動處理狀態變化的邏輯, 使得程序複雜度上升, 難以調試。

computed watch methods

用法: 區別:

  1. 前兩者自動追蹤數據,執行相關函數,最後一個手動調用;
  2. computed是計算屬性,用法與data一致
  3. watch像事件監聽,對象發生變化時,執行相關操作
  4. methods與js中執行方法類似
  5. computed通常只有get屬性
  6. 數據變化的同時進行異步操作或者是比較大的開銷,那麼watch為最佳選擇
  7. watch的對象必須事先聲明

算法相關

各種排序實現

相關數據

"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

2019前端面試經典(html5+css3+JavaScript)

1,2,3請求行,4請求體,5請求體跨域、JSONP 、CORS、postMessage

跨域概念解釋:當前發起請求的域與該請求指向的資源所在的域不一樣。這裡的域指的是這樣的一個概念:我們認為若協議 + 域名 + 端口號均相同,那麼就是同域。 如下表

2019前端面試經典(html5+css3+JavaScript)

jsonp實現

原生
<script>
var script = document.createElement('script');
script.type = 'text/javascript';

// 傳參並指定回調執行函數為onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);

// 回調執行函數
function onBack(res) {
alert(JSON.stringify(res));
}
</script>

jquery
$.ajax({
url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 請求方式為jsonp
jsonpCallback: "onBack", // 自定義回調函數名
data: {}
});
vue
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'onBack'
}).then((res) => {
console.log(res);
})
配合的後端node實現,其他服務器語言也可以
const querystring = require('querystring');
const http = require('http');
const server = http.createServer();
server.on('request', function(req, res) {
var params = qs.parse(req.url.split('?')[1]);
var fn = params.callback;

// jsonp返回設置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');

res.end();
});
server.listen('8080');
jsoup缺點只能實現get請求
複製代碼

CORS:跨源資源共享 Cross-Origin Resource Sharing(CORS),通常服務器設置,若帶cookie請求,則前後端都需要設置 後端常見設置 response.setHeader("Access-Control-Allow-Origin", "www.domain1.com"); // 若有端口需寫全(協議+域名+端口),允許那些外源請求 response.setHeader("Access-Control-Allow-Credentials", "true"); //是否需要驗證

前端示例

原生
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端設置是否帶cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');

xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
jquery
$.ajax({
...
xhrFields: {
withCredentials: true // 前端設置是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie
...
});
複製代碼
postMessage(data,origin)方法接受兩個參數
demo
a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向domain2傳送跨域數據
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
};

// 接受domain2返回數據
window.addEventListener('message', function(e) {
alert('data from domain2 ---> ' + e.data);
}, false);
</script>
b.html 與a.html不同源
<script>
// 接收domain1的數據
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);

var data = JSON.parse(e.data);
if (data) {
data.number = 16;

// 處理後再發回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
複製代碼

osi模型

七層結構:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層 tcp ucp屬於傳輸層;http屬於應用層

http2.0 http1

  1. HTTP2.0的基本單位為二進制幀
  2. HTTP2.0中幀具有優先級
  3. HTTP2.0的多路複用( 1次連接)
  4. HTTP2.0壓縮消息頭
  5. HTTP2.0服務端推送
  6. HTTP2.0只適用於HTTPS的場景

Vue相關

生命週期順序

2019前端面試經典(html5+css3+JavaScript)

組件通信

1.父傳子用props,父用子用ref 子調父用$emit,無關係用Bus

Vuex

組件通信庫,可以避免子組件無法改變props的弊端等 mutations 同步操作, 用於改變狀態 官方不推薦異步 action 執行多個mutaions,官方推薦異步操作 mapState、mapGetters、mapActions使用示例

<template>
<el-dialog :visible.sync="show"></el-dialog>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed:{
//這裡的三點叫做 : 擴展運算符
...mapState({
show:state=>state.dialog.show
}),
}
}
</script>
後兩者類似
複製代碼

VueRouter

定義
var routes = [
{
path:"/one",
component:導入的組件1
},
{
path:"/two",
component:導入的組件2
},
];
// 定義路由組件
var router = new VueRouter({
routes
});
// 定義路由
new Vue({
el:"#box",
router
});
訪問設定的路由後 會將<router-view></router-view>替換成相應的模版
html訪問方式 <router-link to="/one">One</router-link>(類似a標籤)
js訪問方式 this.$router.push('/one');
replace方式 替換當前頁面
攜帶的參數 可以通過this.$route.query.xxxx來獲取
複製代碼

Vue雙向綁定

原理:利用了 Object.defineProperty() 這個方法重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現的。 缺點:雙向數據流是自動管理狀態的, 但是在實際應用中會有很多不得不手動處理狀態變化的邏輯, 使得程序複雜度上升, 難以調試。

computed watch methods

用法: 區別:

  1. 前兩者自動追蹤數據,執行相關函數,最後一個手動調用;
  2. computed是計算屬性,用法與data一致
  3. watch像事件監聽,對象發生變化時,執行相關操作
  4. methods與js中執行方法類似
  5. computed通常只有get屬性
  6. 數據變化的同時進行異步操作或者是比較大的開銷,那麼watch為最佳選擇
  7. watch的對象必須事先聲明

算法相關

各種排序實現

相關數據

2019前端面試經典(html5+css3+JavaScript)

// 冒泡排序: 比較兩個相鄰的項,如果第一個大於第二個則交換他們的位置,元素項向上移動至正確的順序,就好像氣泡往上冒一樣
冒泡demo:
function bubbleSort(arr) {
let len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { //相鄰元素兩兩對比
[arr[j + 1], arr[j]] = [arr[j], arr[j + 1]];
}
}
}
return arr;
}
// 1) 首先,在數組中選擇一箇中間項作為主元
// 2) 創建兩個指針,左邊的指向數組第一個項,右邊的指向最後一個項,移動左指針,直到找到一個比主元大的項,接著,移動右邊的指針,直到找到一個比主元小的項,然後交換它們。重複這個過程,直到
// 左側的指針超過了右側的指針。這個使比主元小的都在左側,比主元大的都在右側。這一步叫劃分操作
// 3) 接著,算法對劃分後的小數組(較主元小的值組成的的小數組, 以及較主元大的值組成的小數組)重複之前的兩個步驟,直到排序完成
快排demo:
function quickSort(arr, left, right) {
let len = arr.length;
let partitionIndex;
left = typeof left !== 'number' ? 0 : left;
right = typeof right !== 'number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
function partition(arr, left, right) { //分區操作
let pivot = left; //設定基準值(pivot)
let index = pivot + 1;
for (let i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index++;
}
}
[arr[pivot], arr[index - 1]] = [arr[index - 1], arr[pivot]];
return index - 1;
}
// 選擇排序:大概思路是找到最小的放在第一位,找到第二小的放在第二位,以此類推 算法複雜度O(n^2)
選擇demo:
function selectionSort(arr) {
\tlet len = arr.length;
\tlet minIndex;
\tfor (let i = 0; i < len - 1; i++) {
\t\tminIndex = i;
\t\tfor (let j = i + 1; j < len; j++) {
\t\t\tif (arr[j] < arr[minIndex]) { //尋找最小的數
\t\t\t minIndex = j; //將最小數的索引保存
\t\t }
\t\t}
\t\t[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
\t}
return arr;
}
// 插入排序:每次排一個數組項,假設數組的第一項已經排序,接著,把第二項與第一項進行對比,第二項是該插入到第一項之前還是之後,第三項是該插入到第一項之前還是第一項之後還是第三項
插入demo:
function insertionSort(arr) {
\tlet len = arr.length;
\tlet preIndex, current;
\tfor (let i = 1; i < len; i++) {
\t preIndex = i - 1;
\t current = arr[i];
\t while (preIndex >= 0 && arr[preIndex] > current) {
\t\t arr[preIndex + 1] = arr[preIndex];
\t\t preIndex--;
\t }
\t arr[preIndex + 1] = current;
\t}
\treturn arr;
}
// 歸併排序:Mozilla Firefox 使用歸併排序作為Array.prototype.sort的實現,而chrome使用快速排序的一個變體實現的,前面三種算法性能不好,但歸併排序性能不錯 算法複雜度O(nlog^n)
// 歸併排序是一種分治算法。本質上就是把一個原始數組切分成較小的數組,直到每個小數組只有一個位置,接著把小數組歸併成較大的數組,在歸併過程中也會完成排序,直到最後只有一個排序完畢的大數組
歸併demo:
function mergeSort(arr) { //採用自上而下的遞歸方法
let len = arr.length;
if(len < 2) {
return arr;
}
let middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right){
let result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
result.push(...left);
result.push(...right);
return result;
}
//堆排序:堆排序把數組當中二叉樹來排序而得名。
// 1)索引0是樹的根節點;2)除根節點為,任意節點N的父節點是N/2;3)節點L的左子節點是2*L;4)節點R的右子節點為2*R + 1
// 本質上就是先構建二叉樹,然後把根節點與最後一個進行交換,然後對剩下對元素進行二叉樹構建,進行交換,直到剩下最後一個
堆demo:
var len; //因為聲明的多個函數都需要數據長度,所以把len設置成為全局變量
function buildMaxHeap(arr) { //建立大頂堆
len = arr.length;
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i);
}
}
function heapify(arr, i) { //堆調整
let left = 2 * i + 1;
let right = 2 * i + 2;
let largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, largest);
}
}
function heapSort(arr) {
buildMaxHeap(arr);
for (let i = arr.length - 1; i > 0; i--) {
[arr[0],arr[i]]=[arr[i],arr[0]];
len--;
heapify(arr, 0);
}
return arr;
}
複製代碼

二分查找

思路 (1)首先,從有序數組的中間的元素開始搜索,如果該元素正好是目標元素(即要查找的元素),則搜索過程結束,否則進行下一步。 (2)如果目標元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半區域查找,然後重複第一步的操作。 (3)如果某一步數組為空,則表示找不到目標元素。

// 非遞歸算法
function binary_search(arr, key) {
let low = 0;
let high = arr.length - 1;
while(low <= high){
let 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;
}
}
}

// 遞歸算法
function binary_search(arr,low, high, key) {
if (low > high){
return -1;
}
let 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);
}
};
複製代碼

二叉樹相關

創建
function Node(data,left,right){
\tthis.data = data;//數值
\tthis.left = left;//左節點
\tthis.right = right;//右節點
};
插入二叉樹
function insert(node,data){
\t//創建一個新的節點
\tlet newNode = new Node(data,null,null);
\t//判斷是否存在根節點,沒有將新節點存入
\tif(node == null){
\t\tnode = newNode;
\t}else{
\t\t//獲取根節點
\t\tlet current = node;
\t\tlet parent;
\t\twhile(true){
\t\t\t//將當前節點保存為父節點
\t\t\tparent = current;
\t\t\t//將小的數據放在左節點
\t\t\tif(data < current.data){
\t\t\t\t//獲取當前節點的左節點
\t\t\t\t//判斷當前節點下的左節點是否有數據
\t\t\t\tcurrent = current.left;
\t\t\t\tif(current == null){
\t\t\t\t\t//如果沒有數據將新節點存入當前節點下的左節點
\t\t\t\t\tparent.left = newNode;
\t\t\t\t\tbreak;
\t\t\t\t}
\t\t\t}else{
\t\t\t\tcurrent = current.right;
\t\t\t\tif(current == null){
\t\t\t\t\tparent.right = newNode;
\t\t\t\t\tbreak;
\t\t\t\t}
\t\t\t}
\t\t}
\t}
}
翻轉二叉樹
function invertTree(node) {
\tif (node !== null) {
\t\tnode.left, node.right = node.left, node.right;
\t\tinvertTree(node.left);
\t\tinvertTree(node.right);
\t}
\treturn node;
}
複製代碼
查找鏈表中倒數第k個結點
2個思路
1:先遍歷出長度,然後查找長度-k+1的值
2:2個指針,一個指針先走k-1,然後兩個一起走到底部,後者就是結果
複製代碼

網絡安全相關

XSS CSRF

XSS(跨站腳本攻擊),惡意的注入html代碼,其他用戶訪問時,會被執行 特點:能注入惡意的HTML/JavaScript代碼到用戶瀏覽的網頁上,從而達到Cookie資料竊取、會話劫持、釣魚欺騙等攻擊 防禦手段:

  • 瀏覽器禁止頁面的JS訪問帶有HttpOnly屬性的Cookie
  • 兩端進行輸入格式檢查
  • 通過編碼轉義的方式進行輸出檢查 CSRF(攻擊跨站請求偽造) 特點:重要操作的所有參數都是可以被攻擊者猜測到的。攻擊者預測出URL的所有參數與參數值,才能成功地構造一個偽造的請求。 防禦手段:
  • token驗證機制,比如請求數據字段中添加一個token,響應請求時校驗其有效性
  • 用戶操作限制,比如驗證碼(繁瑣,用戶體驗差)
  • 請求來源限制,比如限制HTTP Referer才能完成操作(防禦效果相比較差) 實踐中常用第一種

webpack相關

#####打包體積 優化思路

  1. 提取第三方庫或通過引用外部文件的方式引入第三方庫
  2. 代碼壓縮插件UglifyJsPlugin
  3. 服務器啟用gzip壓縮
  4. 按需加載資源文件 require.ensure
  5. 優化devtool中的source-map
  6. 剝離css文件,單獨打包
  7. 去除不必要插件,通常就是開發環境與生產環境用同一套配置文件導致 #####打包效率
  8. 開發環境採用增量構建,啟用熱更新
  9. 開發環境不做無意義的工作如提取css計算文件hash等
  10. 配置devtool
  11. 選擇合適的loader
  12. 個別loader開啟cache 如babel-loader
  13. 第三方庫採用引入方式
  14. 提取公共代碼
  15. 優化構建時的搜索路徑 指明需要構建目錄及不需要構建目錄
  16. 模塊化引入需要的部分

Loader

編寫一個loader

loader就是一個node模塊,它輸出了一個函數。當某種資源需要用這個loader轉換時,這個函數會被調用。並且,這個函數可以通過提供給它的this上下文訪問Loader API。
reverse-txt-loader
定義
module.exports = function(src) {
//src是原文件內容(abcde),下面對內容進行處理,這裡是反轉
var result = src.split('').reverse().join('');
//返回JavaScript源碼,必須是String或者Buffer
return `module.exports = '${result}'`;
}
使用
{
\ttest: /\\.txt$/,
\tuse: [
\t\t{
\t\t\t'./path/reverse-txt-loader'
\t\t}
\t]
},
複製代碼

plugins

使用範圍更廣,通常只需要require()然後添加到plugins數組中,且需要new一個

其他

URL到界面顯示發生了什麼

  1. DNS解析 先本地緩存找,在一層層找 將常見的地址解析成唯一對應的ip地址基本順序為:本地域名服務器->根域名服務器->com頂級域名服務器依次類推下去,找到後記錄並緩存下來如www.google.com為
  2. . -> .com -> google.com. -> www.google.com.
  3. TCP連接 三次握手,只要沒收到確認消息就要重新發
  4. 主機向服務器發送一個建立連接的請求(您好,我想認識您);
  5. 服務器接到請求後發送同意連接的信號(好的,很高興認識您);
  6. 主機接到同意連接的信號後,再次向服務器發送了確認信號(我也很高興認識您),自此,主機與服務器兩者建立了連接。
  7. 發送HTTP請求 瀏覽器會分析這個url,並設置好請求報文發出。請求報文中包括請求行、請求頭、空行、請求主體。https默認請求端口443, http默認80。 常見的http請求如下
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
第一部分:請求行,第一行說明是post請求,以及http1.1版本。
第二部分:請求頭部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:請求數據,第八行。
4. 服務器處理請求並返回HTTP報文
後端處理返回http報文如下
複製代碼
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
第一行為狀態行,(HTTP/1.1)表明HTTP版本為1.1版本,狀態碼為200,狀態消息為(ok)
第二行和第三行為消息報頭,
Date:生成響應的日期和時間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8
第三部分:空行,消息報頭後面的空行是必須的
第四部分:響應正文,服務器返回給客戶端的文本信息。
空行後面的html部分為響應正文。
複製代碼
  1. 瀏覽器解析渲染頁面
  • 通過HTML解析器解析HTML文檔,構建一個DOM Tree,同時通過CSS解析器解析HTML中存在的CSS,構建Style Rules,兩者結合形成一個Attachment。
  • 通過Attachment構造出一個呈現樹(Render Tree)
  • Render Tree構建完畢,進入到佈局階段(layout/reflow),將會為每個階段分配一個應出現在屏幕上的確切座標。
  • 最後將全部的節點遍歷繪製出來後,一個頁面就展現出來了。 遇到script會停下來執行,所以通常把script放在底部
  1. 連接結束

組件封裝

目的:為了重用,提高開發效率和代碼質量 注意:低耦合,單一職責,可複用性,可維護性 常用操作:

  1. 分析佈局
  2. 初步開發
  3. 化繁為簡
  4. 組件抽象

JS異步加載

  1. 動態生成script標籤
  2. 添加h5的async defer屬性,前者亂序不適合依賴性加載
  3. async 是“下載完就執行”, defer 是“渲染完再執行”

css與js動畫差異

  1. css性能好
  2. css代碼邏輯相對簡單
  3. js動畫控制好
  4. js兼容性好
  5. js可實現的動畫多
  6. js可以添加事件

負載均衡

多臺服務器共同協作,不讓其中某一臺或幾臺超額工作,發揮服務器的最大作用

  1. http重定向負載均衡:調度者根據策略選擇服務器以302響應請求,缺點只有第一次有效果,後續操作維持在該服務器
  2. dns負載均衡:解析域名時,訪問多個ip服務器中的一個(可監控性較弱)
  3. 反向代理負載均衡:訪問統一的服務器,由服務器進行調度訪問實際的某個服務器,對統一的服務器要求大,性能受到 服務器群的數量

CDN

內容分發網絡,基本思路是儘可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。

內存洩漏

定義:程序中己動態分配的堆內存由於某種原因程序未釋放或無法釋放引發的各種問題 js中可能出現的內存洩漏情況 結果:變慢,崩潰,延遲大等 原因:

  1. 全局變量
  2. dom清空時,還存在引用
  3. ie中使用閉包
  4. 定時器未清理
  5. 子元素存在引起的內存洩露

避免策略:

  1. 減少不必要的全局變量,或者生命週期較長的對象,及時對無用的數據進行垃圾回收;
  2. 注意程序邏輯,避免“死循環”之類的 ;
  3. 避免創建過多的對象 原則:不用了的東西要及時歸還。
  4. 減少層級過多的引用

babel原理

ES6、7代碼輸入 -> babylon進行解析 -> 得到AST(抽象語法樹)-> plugin用babel-traverse對AST樹進行遍歷轉譯 ->得到新的AST樹->用babel-generator通過AST樹生成ES5代碼、

promise

特性:Promise 對象的錯誤具有冒泡性質,會一直向後傳遞,直到被捕獲為止,也即是說,錯誤總會被下一個catch語句捕獲

js自定義事件

三要素: document.createEvent() event.initEvent() element.dispatchEvent()

demo:
(en:自定義事件名稱,fn:事件處理函數,addEvent:為DOM元素添加自定義事件,triggerEvent:觸發自定義事件)
window.onload = function(){
var demo = document.getElementById("demo");
demo.addEvent("test",function(){console.log("handler1")});
demo.addEvent("test",function(){console.log("handler2")});
demo.onclick = function(){
this.triggerEvent("test");
}
}
Element.prototype.addEvent = function(en,fn){
this.pools = this.pools || {};
if(en in this.pools){
this.pools[en].push(fn);
}else{
this.pools[en] = [];
this.pools[en].push(fn);
}
}
Element.prototype.triggerEvent = function(en){
if(en in this.pools){
var fns = this.pools[en];
for(var i=0,il=fns.length;i<il;i++){
fns[i]();
}
}else{
return;
}
}
複製代碼

es6模塊 commonjs amd cmd

  1. CommonJS 的規範中,每個 JavaScript 文件就是一個獨立的模塊上下文(module context),在這個上下文中默認創建的屬性都是私有的。也就是說,在一個文件定義的變量(還包括函數和類),都是私有的,對其他文件是不可見的。
  2. CommonJS是同步加載模塊,在瀏覽器中會出現堵塞情況,所以不適用
  3. AMD 異步,需要定義回調define方式
  4. es6 一個模塊就是一個獨立的文件,該文件內部的所有變量,外部無法獲取。如果你希望外部能夠讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量
  5. es6還可以導出類、方法,自動適用嚴格模式
"

前端目錄

  1. HTML相關
  2. CSS相關
  3. JAVASCRIPT相關
  4. DOM相關
  5. HTTP相關
  6. VUE相關
  7. 算法相關
  8. 網絡安全相關
  9. webpack相關
  10. 其他

Html相關

1 html語義化

意義:根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化)便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析。 注意:

1.儘可能少的使用無語義的標籤div和span;

2.在語義不明顯時,既可以使用div或者p時,儘量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

3.不要使用純樣式標籤,如:b、font、u等,改用css設置。

4.需要強調的文本,可以包含在strong或者em標籤中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

5.使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

6.表單域要用fieldset標籤包起來,並用legend標籤說明表單的用途;

7.每個input標籤對應的說明文本都需要使用label標籤,並且通過為input設置id屬性,在lable標籤中設置for=someld來讓說明文本和相對應的input關聯起來。

新標籤:

2019前端面試經典(html5+css3+JavaScript)

2 meta viewport相關

<!DOCTYPE html> H5標準聲明,使用 HTML5 doctype,不區分大小寫
<head lang=”en”> 標準的 lang 屬性寫法
<meta charset=’utf-8′> 聲明文檔使用的字符編碼
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> 優先使用 IE 最新版本和 Chrome
<meta name=”description” content=”不超過150個字符”/> 頁面描述
<meta name=”keywords” content=””/> 頁面關鍵詞
<meta name=”author” content=”name, [email protected]”/> 網頁作者
<meta name=”robots” content=”index,follow”/> 搜索引擎抓取
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no”> 為移動設備添加 viewport
<meta name=”apple-mobile-web-app-title” content=”標題”> iOS 設備 begin
<meta name=”apple-mobile-web-app-capable” content=”yes”/> 添加到主屏後的標題(iOS 6 新增)
是否啟用 WebApp 全屏模式,刪除蘋果默認的工具欄和菜單欄
<meta name=”apple-itunes-app” content=”app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL”>
添加智能 App 廣告條 Smart App Banner(iOS 6+ Safari)
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> 設置蘋果工具欄顏色
<meta name=”renderer” content=”webkit”> 啟用360瀏覽器的極速模式(webkit)
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> 避免IE使用兼容模式
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> 不讓百度轉碼
<meta name=”HandheldFriendly” content=”true”> 針對手持設備優化,主要是針對一些老的不識別viewport的瀏覽器,比如黑莓
<meta name=”MobileOptimized” content=”320″> 微軟的老式瀏覽器
<meta name=”screen-orientation” content=”portrait”> uc強制豎屏
<meta name=”x5-orientation” content=”portrait”> QQ強制豎屏
<meta name=”full-screen” content=”yes”> UC強制全屏
<meta name=”x5-fullscreen” content=”true”> QQ強制全屏
<meta name=”browsermode” content=”application”> UC應用模式
<meta name=”x5-page-mode” content=”app”> QQ應用模式
<meta name=”msapplication-tap-highlight” content=”no”> windows phone 點擊無高光
設置頁面不緩存
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
複製代碼

3 canvas 相關

使用前需要獲得上下文環境,暫不支持3d
常用api:
\t1.fillRect(x,y,width,height)實心矩形
\t2.strokeRect(x,y,width,height)空心矩形
\t3.fillText("Hello world",200,200);實心文字
4.strokeText("Hello world",200,300)空心文字
各種東西!!!
複製代碼

新標籤兼容低版本

  1. ie9之前版本通過createElement創建html5新標籤
  2. 引入html5shiv.js

CSS相關

1.盒模型

1.ie盒模型算上border、padding及自身(不算margin),標準的只算上自身窗體的大小 css設置方法如下

/* 標準模型 */
box-sizing:content-box;
/*IE模型*/
box-sizing:border-box;
複製代碼

2.margin、border、padding、content由外到裡 3.幾種獲得寬高的方式

  • dom.style.width/height 這種方式只能取到dom元素內聯樣式所設置的寬高,也就是說如果該節點的樣式是在style標籤中或外聯的CSS文件中設置的話,通過這種方法是獲取不到dom的寬高的。
  • dom.currentStyle.width/height 這種方式獲取的是在頁面渲染完成後的結果,就是說不管是哪種方式設置的樣式,都能獲取到。但這種方式只有IE瀏覽器支持。
  • window.getComputedStyle(dom).width/height 這種方式的原理和2是一樣的,這個可以兼容更多的瀏覽器,通用性好一些。
  • dom.getBoundingClientRect().width/height 這種方式是根據元素在視窗中的絕對位置來獲取寬高的
  • dom.offsetWidth/offsetHeight 這個就沒什麼好說的了,最常用的,也是兼容最好的。

4.拓展 各種獲得寬高的方式

  • 獲取屏幕的高度和寬度(屏幕分辨率): window.screen.height/width
  • 獲取屏幕工作區域的高度和寬度(去掉狀態欄): window.screen.availHeight/availWidth
  • 網頁全文的高度和寬度: document.body.scrollHeight/Width
  • 滾動條捲上去的高度和向右卷的寬度: document.body.scrollTop/scrollLeft
  • 網頁可見區域的高度和寬度(不加邊線): document.body.clientHeight/clientWidth
  • 網頁可見區域的高度和寬度(加邊線): document.body.offsetHeight/offsetWidth

5.邊距重疊解決方案(BFC) BFC原理

  • 內部的box會在垂直方向,一個接一個的放置 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對於從做往右的格式化,否則相反)
  • box垂直方向的距離由margin決定,屬於同一個bfc的兩個相鄰box的margin會發生重疊
  • bfc的區域不會與浮動區域的box重疊
  • bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc裡的元素,反過來,裡面的也不會影響外面的
  • 計算bfc高度的時候,浮動元素也會參與計算 創建bfc
  • float屬性不為none(脫離文檔流)
  • position為absolute或fixed
  • display為inline-block,table-cell,table-caption,flex,inine-flex
  • overflow不為visible
  • 根元素 demo
<section class="top">
\t<h1>上</h1>
\t這塊margin-bottom:30px;
</section>
<!-- 給下面這個塊添加一個父元素,在父元素上創建bfc -->
<div style="overflow:hidden">
\t<section class="bottom">
\t<h1>下</h1>
\t這塊margin-top:50px;
\t</section>
</div>
複製代碼

css reset 和 normalize.css 有什麼區別

  • 兩者都是通過重置樣式,保持瀏覽器樣式的一致性
  • 前者幾乎為所有標籤添加了樣式,後者保持了許多瀏覽器樣式,保持儘可能的一致
  • 後者修復了常見的桌面端和移動端瀏覽器的bug:包含了HTML5元素的顯示設置、預格式化文字的font-size問題、在IE9中SVG的溢出、許多出現在各瀏覽器和操作系統中的與表單相關的bug。
  • 前者中含有大段的繼承鏈
  • 後者模塊化,文檔較前者來說豐富

居中方法

水平方向上

針對inline, 內聯塊inline-block, 內聯表inline-table, inline-flex元素及img,span,button等元素
.text_div{
\ttext-align:center;
}
複製代碼
不定寬塊狀元素居中
.text_div{
margin:0 auto;//且需要設置父級寬度
}
複製代碼
通過給父元素設置 float,然後給父元素設置 position:relative 和 left:50%,子元素設置 position:relative 和 left: -50% 來實現水平居中。
.wrap{
float:left;
position:relative;
left:50%;
clear:both;
}
.wrap-center{
left:-50%;
}
複製代碼

垂直居中

單行內聯(inline-)元素垂直居中 
通過設置內聯元素的高度(height)和行高(line-height)相等,從而使元素垂直居中。
.text_div{
height: 120px;
line-height: 120px;
}
複製代碼
利用表佈局
.father {
display: table;
}
.children {
display: table-cell;
vertical-align: middle;
text-align: center;
}
複製代碼
flex佈局
.center-flex {
display: flex;
flex-direction: column;//上下排列
justify-content: center;
}
複製代碼
絕對佈局方式
已知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
未知高度
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
複製代碼

垂直水平居中根據上方結合

flex方式
.parent {
display: flex;
justify-content: center;
align-items: center;
}
grid方式
.parent {
height: 140px;
display: grid;
}
.child {
margin: auto;
}
複製代碼

css優先級確定

  • 每個選擇器都有權值,權值越大越優先
  • 繼承的樣式優先級低於自身指定樣式
  • !important優先級最高 js也無法修改
  • 權值相同時,靠近元素的樣式優先級高 順序為內聯樣式表(標籤內部)> 內部樣式表(當前文件中)> 外部樣式表(外部文件中)

bfc內容見盒模型

如何清除浮動

不清楚浮動會發生高度塌陷:浮動元素父元素高度自適應(父元素不寫高度時,子元素寫了浮動後,父元素會發生高度塌陷)

  • clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式: {clear:both;height:0;overflow:hidden;}
  • 給浮動元素父級設置高度
  • 父級同時浮動(需要給父級同級元素添加浮動)
  • 父級設置成inline-block,其margin: 0 auto居中方式失效
  • 給父級添加overflow:hidden 清除浮動方法
  • 萬能清除法 after偽類 清浮動(現在主流方法,推薦使用)
.float_div:after{
\tcontent:".";
\tclear:both;
\tdisplay:block;
\theight:0;
\toverflow:hidden;
\tvisibility:hidden;
}
.float_div{
\tzoom:1
}
複製代碼

自適應佈局

思路:

  1. 左側浮動或者絕對定位,然後右側margin撐開
  2. 使用div包含,然後靠負margin形成bfc
  3. 使用flex

畫三角形

#item {
\twidth: 0;
\theight: 0;
\tborder-left: 50px solid transparent;
\tborder-right: 50px solid transparent;
\tborder-top: 50px solid transparent;
\tborder-bottom: 50px solid blue;
\tbackground: white;
}
複製代碼

link @import導入css

  1. link是XHTML標籤,除了加載CSS外,還可以定義RSS等其他事務;@import屬於CSS範疇,只能加載CSS。
  2. link引用CSS時,在頁面載入時同時加載;@import需要頁面網頁完全載入以後加載。
  3. link無兼容問題;@import是在CSS2.1提出的,低版本的瀏覽器不支持。
  4. link支持使用Javascript控制DOM去改變樣式;而@import不支持。

animation

2019前端面試經典(html5+css3+JavaScript)

長寬比方案

  1. 使用padding方式結合calc實現
  2. 長寬一項設置百分比另一項aspect-ratio實現(需藉助插件實現)

display相關

  1. block:div等容器類型
  2. inline:img span等行內類型
  3. table系列:將樣式變成table類型
  4. flex:重點把握,非常強大
  5. grid:同上
  6. inline-block:可設置寬度,兩者間有一點間隙
  7. inherit:繼承父級

JavaScript相關

1 ["1", "2", "3"].map(parseInt)

首先, map接受兩個參數, 一個回調函數 callback, 一個回調函數的this值
其中回調函數接受三個參數 currentValue, index, arrary;
而題目中, map只傳入了回調函數--parseInt.
其次, parseInt 只接受兩個兩個參數 string, radix(基數).
本題理解來說也就是key與 index
所以本題即問
parseInt('1', 0);
parseInt('2', 1);
parseInt('3', 2);
parseInt(string, radix)
string\t必需。要被解析的字符串。
radix 可選。表示要解析的數字的基數。該值介於 2 ~ 36 之間。
如果省略該參數或其值為 0,則數字將以 10 為基礎來解析。如果它以 “0x” 或 “0X” 開頭,將以 16 為基數。
複製代碼

2 [[3,2,1].reduce(Math.pow), [].reduce(Math.pow)]

arr.reduce(callback[, initialValue])
reduce接受兩個參數, 一個回調, 一個初始值.
回調函數接受四個參數 previousValue, currentValue, currentIndex, array
需要注意的是 If the array is empty and no initialValue was provided, TypeError would be thrown.
所以第二個表達式會報異常. 第一個表達式等價於 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
複製代碼

3

var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
我們看到在迭代這個數組的時候, 首先檢查了這個索引值是不是數組的一個屬性, 那麼我們測試一下.
0 in ary; => true
3 in ary; => false
10 in ary; => true
也就是說 從 3 - 9 都是沒有初始化的bug !, 這些索引並不存在與數組中. 在 array 的函數調用的時候是會跳過這些坑的.
複製代碼

4 [typeof null, null instanceof Object]

typeof 返回一個表示類型的字符串.
instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上.
type result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Symbol "symbol"
Host object Implementation-dependent
Function "function"
Object "object"
複製代碼

5 js數據類型

1.number;

2.string;

3.boolean;

4.undefined;

5.null;

6.symbol(ES6新增,文章後面有對著新類型的解釋)Symbol 生成一個全局唯一的值。

7.Object.(包括Object,Array,Function)

6 promise 用法

定義
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
使用
promise.then(function(value) {
// success
}, function(error) {
// failure
});
//等價於:
promise.then(function(){
//success
}).catch(function(){
//failure
})
複製代碼

7 es6 promise ajax

定義
const myHttpClient = url => {
return new Promise((resolve, reject) => {
let client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
}
});
};
使用
myHttpClient('https://www.baidu.com').then(res => {
console.log(res);
}).catch(error => {
console.log(error);
});
複製代碼

8閉包

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);
結果是16
es6通常用let const塊級作用域代替,
閉包缺點,ie中會引起內存洩漏,嚴格來說是ie的缺點不是閉包的問題
複製代碼

9 什麼是立即執行函數?使用立即執行函數的目的是什麼?

常見兩種方式
1.(function(){...})()
(function(x){
\t console.log(x);
})(12345)
2.(function(){...}())
(function(x){
\t console.log(x);
}(12345))
作用 不破壞汙染全局的命名空間,若需要使用,將其用變量傳入如
(function(window){...}(window))
複製代碼

10 async/await 語法

作用:異步代碼的新方式
promise示例
const makeRequest = () => {
return getJSON()
.then(data => {
if (data.needsAnotherRequest) {
return makeAnotherRequest(data)
.then(moreData => {
console.log(moreData)
return moreData
})
} else {
console.log(data)
return data
}
})
}
async/await示例
const makeRequest = async () => {
const data = await getJSON()
if (data.needsAnotherRequest) {
const moreData = await makeAnotherRequest(data);
console.log(moreData)
return moreData
} else {
console.log(data)
return data
}
}
函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串"done")
複製代碼

11 深淺拷貝

let a = {
aa: 1,
bb: 2,
cc: 3,
dd: {
ee: 5,
},
ff: {
gg: 6,
}
};
let d = JSON.parse(JSON.stringify(a));//深複製包含子對象
let c = {...a};//拷貝一層但不包含子對象
let b = a;//淺拷貝
b.bb = 22;
c.cc = 33;
c.dd.ee = 55;
d.ff.gg = 66;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
複製代碼

12數組去重

思路1:定義一個新數組,並存放原數組的第一個元素,然後將元素組一一和新數組的元素對比,若不同則存放在新數組中
思路2:先將原數組排序,在與相鄰的進行比較,如果不同則存入新數組。
思路3:利用對象屬性存在的特性,如果沒有該屬性則存入新數組。
思路4(最常用):使用es6 set
let arr= [1, 2, 3, 3, 5, 7, 2, 6, 8];
console.log([...new Set(arr)]);
複製代碼

13正則實現trim()功能

function myTrim(str) {
let reg = /^\\s+|\\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
複製代碼

14 JS原型

1.每個對象都有 __proto__ 屬性,但只有函數對象才有 prototype 屬性
2.個人粗略理解與python的類方法靜態方法實例方法差不多
複製代碼

15 es6 class

面向對象,java中類
複製代碼

16 JS 如何實現繼承

1.使用原型繼承(既繼承了父類的模板,又繼承了父類的原型對象。優點是繼承了父類的模板,又繼承了父類的原型對象,缺點就是父類實例傳參,不是子類實例化傳參,不符合常規語言的寫法)
2.使用call的方式(繼承了父類的模板,不繼承了父類的原型對象。優點是方便了子類實例傳參,缺點就是不繼承了父類的原型對象)
複製代碼

17 手寫jquery插件

(function ($) {
\t$.fn.myPlugins = function (options) {
\t //參數賦值
\t options = $.extend(defaults, options);//對象合併
\t this.each(function () {
\t //執行代碼邏輯
\t });
\t};
})(jQuery);
$(selector).myPlugins({參數});
複製代碼

18 數組合並去重排序

let arr1 = [1, 25, 2, 26, 1234, 6, 213];
let arr2 = [2, 6, 2134, 6, 31, 623];
let c = [...new Set([...arr1, ...arr2])].sort((a, b) => {
\treturn a - b;
});
複製代碼

19 call apply

作用:在函數調用時改變函數的執行上下文也就是this的值 區別:call採用不定長的參數列表,而apply使用一個參數數組。 性能優化圖

20 for 中setTimeOut

要為循環題創建不同的循環副本

21 sort函數

V8 引擎 sort 函數只給出了兩種排序 InsertionSort 和 QuickSort,數量小於10的數組使用 插入,比10大的數組則使用 快排.

23 jquery綁定方式

  1. click後者覆蓋
  2. bind後者覆蓋
  3. on(jquery>=1.7)
  4. live
  5. delegate

24 事件流向

  1. 冒泡:子節點一層層冒泡到根節點
  2. 捕獲順序與冒泡相反
  3. addEventListener最後個參數true代表捕獲反之代表冒泡
  4. 阻止冒泡不停止父節點捕獲

25原生操作class

//判斷有無
function hasClass(ele, cls) {
\treturn ele.className.match(new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)"));
}
//添加
function addClass(ele, cls) {
\tif (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
//刪除
function removeClass(ele, cls) {
\tif (hasClass(ele, cls)) {
\t\tlet reg = new RegExp("(\\\\s|^)" + cls + "(\\\\s|$)");
\t\tele.className = ele.className.replace(reg, " ");
\t}
}
html5中加入classList
一系列操作
兼容至IE10
複製代碼

DOM相關

dom事件模型

DOM之事件模型分腳本模型、內聯模型(同類一個,後者覆蓋)、動態綁定(同類多個) demo

<body>
<!--行內綁定:腳本模型-->
<button onclick="javascrpt:alert('Hello')">Hello1</button>
<!--內聯模型-->
<button onclick="showHello()">Hello2</button>
<!--動態綁定-->
<button id="btn3">Hello3</button>
</body>
<script>
/*DOM0:同一個元素,同類事件只能添加一個,如果添加多個,
* 後面添加的會覆蓋之前添加的*/
function shoeHello() {
alert("Hello");
}
var btn3 = document.getElementById("btn3");
btn3.onclick = function () {
alert("Hello");
}
/*DOM2:可以給同一個元素添加多個同類事件*/
btn3.addEventListener("click",function () {
alert("hello1");
});
btn3.addEventListener("click",function () {
alert("hello2");
})
if (btn3.attachEvent){
/*IE*/
btn3.attachEvent("onclick",function () {
alert("IE Hello1");
})
}else {
/*W3C*/
btn3.addEventListener("click",function () {
alert("W3C Hello");
})
}
</script>
複製代碼

冒泡解釋:當點擊一個元素觸發事件時. 事件會先從元素的最外層父元素一層一層進入到觸發的元素, 然後在從觸發元素一層一層返回到最外層父元素, 從最外層一層一層進入的階段叫事件捕獲階段, 從最裡層一層一層往外的階段叫事件冒泡,

移動端觸摸事件

①touchstart:當手指觸碰到屏幕的時候觸發 ②touchmove:當手指在屏幕上滑動的時候觸發 ③touchend:當手指離開屏幕的時候時候觸發 ④touchcancel事件:當系統停止跟蹤觸摸的時候觸發(這個事件很少會用,一般不做深入研究)。 電話接入或者彈出信息等其他事件切入 event:

  1. touches:表示當前跟蹤的觸摸操作的touch對象的數組。
  2. targetTouches:特定於事件目標的Touch對象的數組。
  3. changeTouches:表示自上次觸摸以來發生了什麼改變的Touch對象的數組。

每個touch對象包含的屬性

  1. clientX:觸摸目標在視口中的x座標。
  2. clientY:觸摸目標在視口中的y座標。
  3. identifier:標識觸摸的唯一ID。
  4. pageX:觸摸目標在頁面中的x座標。
  5. pageY:觸摸目標在頁面中的y座標。
  6. screenX:觸摸目標在屏幕中的x座標。
  7. screenY:觸摸目標在屏幕中的y座標。
  8. target:觸目的DOM節點目標。

事件委託

參考定義:事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件 好處:給重複的節點添加相同操作,減少dom交互,提高性能 實現思路:給父組件添加事件,通過事件冒泡,排查元素是否為指定元素,並進行系列操作

HTTP相關

常見狀態碼

2開頭 (請求成功)表示成功處理了請求的狀態代碼。

200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。 201 (已創建) 請求成功並且服務器創建了新的資源。 202 (已接受) 服務器已接受請求,但尚未處理。 203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。 204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。 205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。 206 (部分內容) 服務器成功處理了部分 GET 請求。

3開頭 (請求被重定向)表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。 304 (未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4開頭 (請求錯誤)這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

400 (錯誤請求) 服務器不理解請求的語法。 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。 403 (禁止) 服務器拒絕請求。 404 (未找到) 服務器找不到請求的網頁。 405 (方法禁用) 禁用請求中指定的方法。 406 (不接受) 無法使用請求的內容特性響應請求的網頁。 407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。 408 (請求超時) 服務器等候請求時發生超時。 409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。 410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。 411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。 412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。 413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。 414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。 415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。 416 (請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。 417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。

5開頭(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

緩存

  1. Expires在http1.0中使用,與服務器時間有誤差,在1.1中由Cache-control替代

2. cdn

Cache-Control 和 Etag 的區別

如下圖

2019前端面試經典(html5+css3+JavaScript)

Cookie sessionStorage localStorage

共同點:都是保存在瀏覽器端,且同源的。 區別:cookie數據始終在同源的http請求中攜帶,即cookie在瀏覽器和服務器間來回傳遞。而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。cookie數據不能超過4k(適合保存小數據)。 sessionStorage和localStorage容量較大,數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效。localStorage:始終有效,窗口或瀏覽器關閉也一直保存,需手動清楚;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。作用域不同。 sessionStorage不在不同的瀏覽器窗口中共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

應用場景:localStorage:常用於長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數據。sessionStorage :敏感賬號一次性登錄; cookies與服務器交互。

請求行,請求頭,請求體詳解

2019前端面試經典(html5+css3+JavaScript)

1,2,3請求行,4請求體,5請求體跨域、JSONP 、CORS、postMessage

跨域概念解釋:當前發起請求的域與該請求指向的資源所在的域不一樣。這裡的域指的是這樣的一個概念:我們認為若協議 + 域名 + 端口號均相同,那麼就是同域。 如下表

2019前端面試經典(html5+css3+JavaScript)

jsonp實現

原生
<script>
var script = document.createElement('script');
script.type = 'text/javascript';

// 傳參並指定回調執行函數為onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);

// 回調執行函數
function onBack(res) {
alert(JSON.stringify(res));
}
</script>

jquery
$.ajax({
url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 請求方式為jsonp
jsonpCallback: "onBack", // 自定義回調函數名
data: {}
});
vue
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'onBack'
}).then((res) => {
console.log(res);
})
配合的後端node實現,其他服務器語言也可以
const querystring = require('querystring');
const http = require('http');
const server = http.createServer();
server.on('request', function(req, res) {
var params = qs.parse(req.url.split('?')[1]);
var fn = params.callback;

// jsonp返回設置
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.write(fn + '(' + JSON.stringify(params) + ')');

res.end();
});
server.listen('8080');
jsoup缺點只能實現get請求
複製代碼

CORS:跨源資源共享 Cross-Origin Resource Sharing(CORS),通常服務器設置,若帶cookie請求,則前後端都需要設置 後端常見設置 response.setHeader("Access-Control-Allow-Origin", "www.domain1.com"); // 若有端口需寫全(協議+域名+端口),允許那些外源請求 response.setHeader("Access-Control-Allow-Credentials", "true"); //是否需要驗證

前端示例

原生
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端設置是否帶cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');

xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
jquery
$.ajax({
...
xhrFields: {
withCredentials: true // 前端設置是否帶cookie
},
crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie
...
});
複製代碼
postMessage(data,origin)方法接受兩個參數
demo
a.html
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向domain2傳送跨域數據
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
};

// 接受domain2返回數據
window.addEventListener('message', function(e) {
alert('data from domain2 ---> ' + e.data);
}, false);
</script>
b.html 與a.html不同源
<script>
// 接收domain1的數據
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);

var data = JSON.parse(e.data);
if (data) {
data.number = 16;

// 處理後再發回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
複製代碼

osi模型

七層結構:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層 tcp ucp屬於傳輸層;http屬於應用層

http2.0 http1

  1. HTTP2.0的基本單位為二進制幀
  2. HTTP2.0中幀具有優先級
  3. HTTP2.0的多路複用( 1次連接)
  4. HTTP2.0壓縮消息頭
  5. HTTP2.0服務端推送
  6. HTTP2.0只適用於HTTPS的場景

Vue相關

生命週期順序

2019前端面試經典(html5+css3+JavaScript)

組件通信

1.父傳子用props,父用子用ref 子調父用$emit,無關係用Bus

Vuex

組件通信庫,可以避免子組件無法改變props的弊端等 mutations 同步操作, 用於改變狀態 官方不推薦異步 action 執行多個mutaions,官方推薦異步操作 mapState、mapGetters、mapActions使用示例

<template>
<el-dialog :visible.sync="show"></el-dialog>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed:{
//這裡的三點叫做 : 擴展運算符
...mapState({
show:state=>state.dialog.show
}),
}
}
</script>
後兩者類似
複製代碼

VueRouter

定義
var routes = [
{
path:"/one",
component:導入的組件1
},
{
path:"/two",
component:導入的組件2
},
];
// 定義路由組件
var router = new VueRouter({
routes
});
// 定義路由
new Vue({
el:"#box",
router
});
訪問設定的路由後 會將<router-view></router-view>替換成相應的模版
html訪問方式 <router-link to="/one">One</router-link>(類似a標籤)
js訪問方式 this.$router.push('/one');
replace方式 替換當前頁面
攜帶的參數 可以通過this.$route.query.xxxx來獲取
複製代碼

Vue雙向綁定

原理:利用了 Object.defineProperty() 這個方法重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現的。 缺點:雙向數據流是自動管理狀態的, 但是在實際應用中會有很多不得不手動處理狀態變化的邏輯, 使得程序複雜度上升, 難以調試。

computed watch methods

用法: 區別:

  1. 前兩者自動追蹤數據,執行相關函數,最後一個手動調用;
  2. computed是計算屬性,用法與data一致
  3. watch像事件監聽,對象發生變化時,執行相關操作
  4. methods與js中執行方法類似
  5. computed通常只有get屬性
  6. 數據變化的同時進行異步操作或者是比較大的開銷,那麼watch為最佳選擇
  7. watch的對象必須事先聲明

算法相關

各種排序實現

相關數據

2019前端面試經典(html5+css3+JavaScript)

// 冒泡排序: 比較兩個相鄰的項,如果第一個大於第二個則交換他們的位置,元素項向上移動至正確的順序,就好像氣泡往上冒一樣
冒泡demo:
function bubbleSort(arr) {
let len = arr.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { //相鄰元素兩兩對比
[arr[j + 1], arr[j]] = [arr[j], arr[j + 1]];
}
}
}
return arr;
}
// 1) 首先,在數組中選擇一箇中間項作為主元
// 2) 創建兩個指針,左邊的指向數組第一個項,右邊的指向最後一個項,移動左指針,直到找到一個比主元大的項,接著,移動右邊的指針,直到找到一個比主元小的項,然後交換它們。重複這個過程,直到
// 左側的指針超過了右側的指針。這個使比主元小的都在左側,比主元大的都在右側。這一步叫劃分操作
// 3) 接著,算法對劃分後的小數組(較主元小的值組成的的小數組, 以及較主元大的值組成的小數組)重複之前的兩個步驟,直到排序完成
快排demo:
function quickSort(arr, left, right) {
let len = arr.length;
let partitionIndex;
left = typeof left !== 'number' ? 0 : left;
right = typeof right !== 'number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
function partition(arr, left, right) { //分區操作
let pivot = left; //設定基準值(pivot)
let index = pivot + 1;
for (let i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
[arr[i], arr[index]] = [arr[index], arr[i]];
index++;
}
}
[arr[pivot], arr[index - 1]] = [arr[index - 1], arr[pivot]];
return index - 1;
}
// 選擇排序:大概思路是找到最小的放在第一位,找到第二小的放在第二位,以此類推 算法複雜度O(n^2)
選擇demo:
function selectionSort(arr) {
\tlet len = arr.length;
\tlet minIndex;
\tfor (let i = 0; i < len - 1; i++) {
\t\tminIndex = i;
\t\tfor (let j = i + 1; j < len; j++) {
\t\t\tif (arr[j] < arr[minIndex]) { //尋找最小的數
\t\t\t minIndex = j; //將最小數的索引保存
\t\t }
\t\t}
\t\t[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
\t}
return arr;
}
// 插入排序:每次排一個數組項,假設數組的第一項已經排序,接著,把第二項與第一項進行對比,第二項是該插入到第一項之前還是之後,第三項是該插入到第一項之前還是第一項之後還是第三項
插入demo:
function insertionSort(arr) {
\tlet len = arr.length;
\tlet preIndex, current;
\tfor (let i = 1; i < len; i++) {
\t preIndex = i - 1;
\t current = arr[i];
\t while (preIndex >= 0 && arr[preIndex] > current) {
\t\t arr[preIndex + 1] = arr[preIndex];
\t\t preIndex--;
\t }
\t arr[preIndex + 1] = current;
\t}
\treturn arr;
}
// 歸併排序:Mozilla Firefox 使用歸併排序作為Array.prototype.sort的實現,而chrome使用快速排序的一個變體實現的,前面三種算法性能不好,但歸併排序性能不錯 算法複雜度O(nlog^n)
// 歸併排序是一種分治算法。本質上就是把一個原始數組切分成較小的數組,直到每個小數組只有一個位置,接著把小數組歸併成較大的數組,在歸併過程中也會完成排序,直到最後只有一個排序完畢的大數組
歸併demo:
function mergeSort(arr) { //採用自上而下的遞歸方法
let len = arr.length;
if(len < 2) {
return arr;
}
let middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right){
let result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
result.push(...left);
result.push(...right);
return result;
}
//堆排序:堆排序把數組當中二叉樹來排序而得名。
// 1)索引0是樹的根節點;2)除根節點為,任意節點N的父節點是N/2;3)節點L的左子節點是2*L;4)節點R的右子節點為2*R + 1
// 本質上就是先構建二叉樹,然後把根節點與最後一個進行交換,然後對剩下對元素進行二叉樹構建,進行交換,直到剩下最後一個
堆demo:
var len; //因為聲明的多個函數都需要數據長度,所以把len設置成為全局變量
function buildMaxHeap(arr) { //建立大頂堆
len = arr.length;
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i);
}
}
function heapify(arr, i) { //堆調整
let left = 2 * i + 1;
let right = 2 * i + 2;
let largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, largest);
}
}
function heapSort(arr) {
buildMaxHeap(arr);
for (let i = arr.length - 1; i > 0; i--) {
[arr[0],arr[i]]=[arr[i],arr[0]];
len--;
heapify(arr, 0);
}
return arr;
}
複製代碼

二分查找

思路 (1)首先,從有序數組的中間的元素開始搜索,如果該元素正好是目標元素(即要查找的元素),則搜索過程結束,否則進行下一步。 (2)如果目標元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半區域查找,然後重複第一步的操作。 (3)如果某一步數組為空,則表示找不到目標元素。

// 非遞歸算法
function binary_search(arr, key) {
let low = 0;
let high = arr.length - 1;
while(low <= high){
let 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;
}
}
}

// 遞歸算法
function binary_search(arr,low, high, key) {
if (low > high){
return -1;
}
let 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);
}
};
複製代碼

二叉樹相關

創建
function Node(data,left,right){
\tthis.data = data;//數值
\tthis.left = left;//左節點
\tthis.right = right;//右節點
};
插入二叉樹
function insert(node,data){
\t//創建一個新的節點
\tlet newNode = new Node(data,null,null);
\t//判斷是否存在根節點,沒有將新節點存入
\tif(node == null){
\t\tnode = newNode;
\t}else{
\t\t//獲取根節點
\t\tlet current = node;
\t\tlet parent;
\t\twhile(true){
\t\t\t//將當前節點保存為父節點
\t\t\tparent = current;
\t\t\t//將小的數據放在左節點
\t\t\tif(data < current.data){
\t\t\t\t//獲取當前節點的左節點
\t\t\t\t//判斷當前節點下的左節點是否有數據
\t\t\t\tcurrent = current.left;
\t\t\t\tif(current == null){
\t\t\t\t\t//如果沒有數據將新節點存入當前節點下的左節點
\t\t\t\t\tparent.left = newNode;
\t\t\t\t\tbreak;
\t\t\t\t}
\t\t\t}else{
\t\t\t\tcurrent = current.right;
\t\t\t\tif(current == null){
\t\t\t\t\tparent.right = newNode;
\t\t\t\t\tbreak;
\t\t\t\t}
\t\t\t}
\t\t}
\t}
}
翻轉二叉樹
function invertTree(node) {
\tif (node !== null) {
\t\tnode.left, node.right = node.left, node.right;
\t\tinvertTree(node.left);
\t\tinvertTree(node.right);
\t}
\treturn node;
}
複製代碼
查找鏈表中倒數第k個結點
2個思路
1:先遍歷出長度,然後查找長度-k+1的值
2:2個指針,一個指針先走k-1,然後兩個一起走到底部,後者就是結果
複製代碼

網絡安全相關

XSS CSRF

XSS(跨站腳本攻擊),惡意的注入html代碼,其他用戶訪問時,會被執行 特點:能注入惡意的HTML/JavaScript代碼到用戶瀏覽的網頁上,從而達到Cookie資料竊取、會話劫持、釣魚欺騙等攻擊 防禦手段:

  • 瀏覽器禁止頁面的JS訪問帶有HttpOnly屬性的Cookie
  • 兩端進行輸入格式檢查
  • 通過編碼轉義的方式進行輸出檢查 CSRF(攻擊跨站請求偽造) 特點:重要操作的所有參數都是可以被攻擊者猜測到的。攻擊者預測出URL的所有參數與參數值,才能成功地構造一個偽造的請求。 防禦手段:
  • token驗證機制,比如請求數據字段中添加一個token,響應請求時校驗其有效性
  • 用戶操作限制,比如驗證碼(繁瑣,用戶體驗差)
  • 請求來源限制,比如限制HTTP Referer才能完成操作(防禦效果相比較差) 實踐中常用第一種

webpack相關

#####打包體積 優化思路

  1. 提取第三方庫或通過引用外部文件的方式引入第三方庫
  2. 代碼壓縮插件UglifyJsPlugin
  3. 服務器啟用gzip壓縮
  4. 按需加載資源文件 require.ensure
  5. 優化devtool中的source-map
  6. 剝離css文件,單獨打包
  7. 去除不必要插件,通常就是開發環境與生產環境用同一套配置文件導致 #####打包效率
  8. 開發環境採用增量構建,啟用熱更新
  9. 開發環境不做無意義的工作如提取css計算文件hash等
  10. 配置devtool
  11. 選擇合適的loader
  12. 個別loader開啟cache 如babel-loader
  13. 第三方庫採用引入方式
  14. 提取公共代碼
  15. 優化構建時的搜索路徑 指明需要構建目錄及不需要構建目錄
  16. 模塊化引入需要的部分

Loader

編寫一個loader

loader就是一個node模塊,它輸出了一個函數。當某種資源需要用這個loader轉換時,這個函數會被調用。並且,這個函數可以通過提供給它的this上下文訪問Loader API。
reverse-txt-loader
定義
module.exports = function(src) {
//src是原文件內容(abcde),下面對內容進行處理,這裡是反轉
var result = src.split('').reverse().join('');
//返回JavaScript源碼,必須是String或者Buffer
return `module.exports = '${result}'`;
}
使用
{
\ttest: /\\.txt$/,
\tuse: [
\t\t{
\t\t\t'./path/reverse-txt-loader'
\t\t}
\t]
},
複製代碼

plugins

使用範圍更廣,通常只需要require()然後添加到plugins數組中,且需要new一個

其他

URL到界面顯示發生了什麼

  1. DNS解析 先本地緩存找,在一層層找 將常見的地址解析成唯一對應的ip地址基本順序為:本地域名服務器->根域名服務器->com頂級域名服務器依次類推下去,找到後記錄並緩存下來如www.google.com為
  2. . -> .com -> google.com. -> www.google.com.
  3. TCP連接 三次握手,只要沒收到確認消息就要重新發
  4. 主機向服務器發送一個建立連接的請求(您好,我想認識您);
  5. 服務器接到請求後發送同意連接的信號(好的,很高興認識您);
  6. 主機接到同意連接的信號後,再次向服務器發送了確認信號(我也很高興認識您),自此,主機與服務器兩者建立了連接。
  7. 發送HTTP請求 瀏覽器會分析這個url,並設置好請求報文發出。請求報文中包括請求行、請求頭、空行、請求主體。https默認請求端口443, http默認80。 常見的http請求如下
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
第一部分:請求行,第一行說明是post請求,以及http1.1版本。
第二部分:請求頭部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:請求數據,第八行。
4. 服務器處理請求並返回HTTP報文
後端處理返回http報文如下
複製代碼
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
第一行為狀態行,(HTTP/1.1)表明HTTP版本為1.1版本,狀態碼為200,狀態消息為(ok)
第二行和第三行為消息報頭,
Date:生成響應的日期和時間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8
第三部分:空行,消息報頭後面的空行是必須的
第四部分:響應正文,服務器返回給客戶端的文本信息。
空行後面的html部分為響應正文。
複製代碼
  1. 瀏覽器解析渲染頁面
  • 通過HTML解析器解析HTML文檔,構建一個DOM Tree,同時通過CSS解析器解析HTML中存在的CSS,構建Style Rules,兩者結合形成一個Attachment。
  • 通過Attachment構造出一個呈現樹(Render Tree)
  • Render Tree構建完畢,進入到佈局階段(layout/reflow),將會為每個階段分配一個應出現在屏幕上的確切座標。
  • 最後將全部的節點遍歷繪製出來後,一個頁面就展現出來了。 遇到script會停下來執行,所以通常把script放在底部
  1. 連接結束

組件封裝

目的:為了重用,提高開發效率和代碼質量 注意:低耦合,單一職責,可複用性,可維護性 常用操作:

  1. 分析佈局
  2. 初步開發
  3. 化繁為簡
  4. 組件抽象

JS異步加載

  1. 動態生成script標籤
  2. 添加h5的async defer屬性,前者亂序不適合依賴性加載
  3. async 是“下載完就執行”, defer 是“渲染完再執行”

css與js動畫差異

  1. css性能好
  2. css代碼邏輯相對簡單
  3. js動畫控制好
  4. js兼容性好
  5. js可實現的動畫多
  6. js可以添加事件

負載均衡

多臺服務器共同協作,不讓其中某一臺或幾臺超額工作,發揮服務器的最大作用

  1. http重定向負載均衡:調度者根據策略選擇服務器以302響應請求,缺點只有第一次有效果,後續操作維持在該服務器
  2. dns負載均衡:解析域名時,訪問多個ip服務器中的一個(可監控性較弱)
  3. 反向代理負載均衡:訪問統一的服務器,由服務器進行調度訪問實際的某個服務器,對統一的服務器要求大,性能受到 服務器群的數量

CDN

內容分發網絡,基本思路是儘可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。

內存洩漏

定義:程序中己動態分配的堆內存由於某種原因程序未釋放或無法釋放引發的各種問題 js中可能出現的內存洩漏情況 結果:變慢,崩潰,延遲大等 原因:

  1. 全局變量
  2. dom清空時,還存在引用
  3. ie中使用閉包
  4. 定時器未清理
  5. 子元素存在引起的內存洩露

避免策略:

  1. 減少不必要的全局變量,或者生命週期較長的對象,及時對無用的數據進行垃圾回收;
  2. 注意程序邏輯,避免“死循環”之類的 ;
  3. 避免創建過多的對象 原則:不用了的東西要及時歸還。
  4. 減少層級過多的引用

babel原理

ES6、7代碼輸入 -> babylon進行解析 -> 得到AST(抽象語法樹)-> plugin用babel-traverse對AST樹進行遍歷轉譯 ->得到新的AST樹->用babel-generator通過AST樹生成ES5代碼、

promise

特性:Promise 對象的錯誤具有冒泡性質,會一直向後傳遞,直到被捕獲為止,也即是說,錯誤總會被下一個catch語句捕獲

js自定義事件

三要素: document.createEvent() event.initEvent() element.dispatchEvent()

demo:
(en:自定義事件名稱,fn:事件處理函數,addEvent:為DOM元素添加自定義事件,triggerEvent:觸發自定義事件)
window.onload = function(){
var demo = document.getElementById("demo");
demo.addEvent("test",function(){console.log("handler1")});
demo.addEvent("test",function(){console.log("handler2")});
demo.onclick = function(){
this.triggerEvent("test");
}
}
Element.prototype.addEvent = function(en,fn){
this.pools = this.pools || {};
if(en in this.pools){
this.pools[en].push(fn);
}else{
this.pools[en] = [];
this.pools[en].push(fn);
}
}
Element.prototype.triggerEvent = function(en){
if(en in this.pools){
var fns = this.pools[en];
for(var i=0,il=fns.length;i<il;i++){
fns[i]();
}
}else{
return;
}
}
複製代碼

es6模塊 commonjs amd cmd

  1. CommonJS 的規範中,每個 JavaScript 文件就是一個獨立的模塊上下文(module context),在這個上下文中默認創建的屬性都是私有的。也就是說,在一個文件定義的變量(還包括函數和類),都是私有的,對其他文件是不可見的。
  2. CommonJS是同步加載模塊,在瀏覽器中會出現堵塞情況,所以不適用
  3. AMD 異步,需要定義回調define方式
  4. es6 一個模塊就是一個獨立的文件,該文件內部的所有變量,外部無法獲取。如果你希望外部能夠讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量
  5. es6還可以導出類、方法,自動適用嚴格模式
2019前端面試經典(html5+css3+JavaScript)

"

相關推薦

推薦中...