最近在掘金上刷到jsliang小夥的一篇文章jsliang 的 2019 面試準備,深受啓發,恰巧本身最近也在準備面試,因此趁着此黃金時期寫下此文章,作一些前端方面的總結,鞏固知識的同時也但願對行走在路上的大家有所幫助。javascript
首先,咱們知道HTML5其實就是對HTML標準的第五次修改,咱們廣義上說的HTML5,實際是包過HTML,CSS,JavaScript在內的一套技術組合.css
它的主要目標呢就是將互聯網語義話,以便更好的被人類還有機器閱讀,同時可以更好地支持各類媒體的嵌入,好比圖片,連接,音樂等非文字元素.html
我認爲,它有倆大特色:首先,強化了web網頁的表現性能.其次,追加了本地數據庫等web應用的功能,提供了更多能支持網絡應用的標準集.前端
拓展:vue
web數據庫呢實際上就是以web查詢接口方式訪問的數據庫資源,它將數據庫技術和web技術融合在一塊兒,使數據庫成爲了web的重要有機組成部分.html5
它的工做過程能夠簡單的描述成:用戶經過瀏覽器的操做界面以交互的方式經由web服務器來訪問數據庫.java
萬維網的簡稱web,node
Web的工做步驟以下。webpack
(1)用戶打開客戶端計算機中的瀏覽器軟件(例如Internet Explorer)。css3
(2)用戶輸入要啓動的Web主頁的URL地址,瀏覽器將生成一個HTTP請求。
(3)瀏覽器鏈接到指定的Web服務器,併發送HTTP請求。
(4)Web服務器接到HTTP請求,根據請求的內容不一樣做相應的處理,再將網頁以HTML文件格式發回給瀏覽器。
(5)瀏覽器將網頁顯示到屏幕上。
超文本標記語言,就是建立網頁的計算機語言 HTML(Hyper Text Markup Language)
咱們所說的網頁其實就是一個HTML文檔,文檔內容由文本和HTML標記組成,擴展名是.html或.htm
HTML標記:它的做用是告訴瀏覽器咱們頁面的結構和格式.若是將特定的英文單詞放入標記中就是標籤
HTML程序:放在中,由文件頭和文件體組成.
HTML規範:也就是HTML標準,是由W3C(萬維網聯盟)制定的.
HTML程序的編輯環境:任何文本編輯器.
HTML程序的運行環境:任何的瀏覽器
可拓展標記語言,是用來定義其它語言的一種元語言.
XML文檔,由字符數據和標記組成.它的語義約束是DTD
文檔類型定義,基本格式:
咱們知道瀏覽器解析css的倆種模式是: 標準模式和怪異模式
標準模式是指按w3c的標準解析執行代碼,而怪異模式是指瀏覽器按它本身的方式解析執行.
而瀏覽器以哪一種模式解釋就是與你網頁中的DTD聲明有關.
若沒有寫DTD的話會使頁面進入怪異模式.
由於HTML5沒有使用SGML或者XHTML,是一個全新的東西,因此不須要參考DTD
結構上大體相同,本質上不一樣:
1.語法要求不一樣,html中不區分大小寫,xml中更嚴格.
2.標記不一樣,html使用固有的標記,xml沒有固有的標記.
3.做用不一樣,html顯示數據,xml描述數據,盛放數據.
注:
XML不是HTML的替代品,由於它們是倆種不一樣用途的語言.
XHTML是更嚴格更純淨的 HTML 版本,但如今已經再也不使用XHTML。
.htm與.html沒有本質上的區別,表示的是同一種文件,只是適用於不一樣的環境之下.DOS(磁盤操做系統)只能識別8 + 3的文件名,因此只能識別.htm而不能識別.html
1.文檔聲明上:html4比較複雜,而html5只有一小段<!DOCTYPE html>
2.結構語義上:html4沒有體現語義化的標籤,而html5有
3.同時h5又新添了不少表單元素的屬性和類型
4.功能上HTML5更增強大,好比能夠利用canvas標籤配合js來實現繪圖功能,也好比新增的視頻標籤video,以及新增的表單元素類型,像email,number,range,data等
1.新的文檔類型
2.腳本和連接無需type
3.語義標籤Header和Footer
4.Hgroup標籤,對h1~h6進行分組。
5.標記元素mark高亮標籤
6.圖形元素figure和figcaption
7.新的表單控件,好比data,number,range,color等等
8.新的表單屬性,好比autofocus、autocomplete、multiple、 placeholder、pattern等等
9.新的功能性標籤:audio、vidio
10.強大的繪圖標籤canvas
11.離線存儲localstorage和sessionstorage
1.默認參數
2.字符串模板
3.多行字符串
4.拆包表達式
5.改進的對象表達式
6.箭頭函數
離線存儲表示的是用戶沒有與因特網連接時,能夠正常訪問站點或應用.
原理是基於一個新建的.appcache文件的緩存機制,經過這個文件上的解析清單離線存儲資源,這些資源就會像cookie同樣被保存下來,當在沒有網絡的狀況下,瀏覽器就會經過被離線存儲的數據進行頁面展現.
在咱們H5中提供了倆種在客戶端存儲數據的新方法:
localStorage和sessionStorage
而在這以前呢,這些功能都是由cookie完成的,只不過cookie的存儲量過小了最多也才4k,因此不適合大量數據的存儲.
設置cookie
document.cookie = "user=wangxiansheng"
alert(document.cookie)
複製代碼
設置過時時間
//expires:過時時間, 接受一個日期對象
var d = new Date()
d.setTime(d.getTime() + 2 * 24 * 60 * 60 * 1000)
var expires = d.toUTCString();
//一個條目包含保存的鍵值對和過時時間
document.cookie = `demo=wangpei;expires=${expires}`;
console.log(document.cookie);
複製代碼
它們倆都是H5新添的離線存儲方法,而且兩種方式保存的數據都僅限於該頁面的協議,但不一樣之處在於:
localStorage它的存儲沒有時間限制,一週或者一個月一年,數據仍然存在.
而sessionStorage裏面存儲的數據會在瀏覽器會話結束時被清除
在兼容性上,各瀏覽器支持localStorage和sessionStorage的容量上限不一樣.在ie8以上是支持的,不包過ie8.
chrome4支持localStorage,chrome5支持sessionStorage.
第一點,在存儲量上,cookie過小了,最多隻能存儲4K.
第二點,cookie能夠設置過時時間,若是沒有設置則默認是在關閉窗口或者回話窗過時,但localStorage和sessionStorage沒有提供設置過時時間的功能,但咱們能夠在存儲的時候加上時間,之後在取值的時候判斷一下localStorage是否過時就能夠了.
在線狀態下,瀏覽器要是發現html頭部有manifast屬性的話,它會請求manifast文件,如果第一次訪問app,那麼瀏覽器就會根據mainfest文件的內容下載對應的資源進行離線存儲
離線狀態下,已經訪問過app而且資源已經離線存儲了,那麼瀏覽器就會使用離線的資源加載頁面,而後瀏覽器會對比新的manifest文件與舊的manifest文件,若是文件沒有發生改變,就不作任何操做,若是文件改變了,那麼就會從新下載文件中的資源並進行離線存儲.
ie支持userData存儲數據.可是基本已經不多使用了,除非有很強的瀏覽器兼容需求.
在幾個主流的瀏覽器中,好比ie瀏覽器,ie8如下是不支持的,ie9支持部分,好比video標籤是支持的.ie10以上支持
還有像Chrome這樣的高級瀏覽器,它的3-5支持大部分,在6以上就所有支持了.
咱們知道,表單元素的自動完成功能就是輸入框輸入內容的時候,瀏覽器會從你之前的同名輸入框的歷史記錄中查找出相似的內容並列舉在輸入框下面,當有時咱們但願使用AJAX技術從數據庫搜索並列舉而不是根據瀏覽器的歷史記錄搜索,因此此時咱們就須要將form的自動完成功能給關閉.
在ie瀏覽器下,咱們能夠在瀏覽器的設置中的internet選項菜單內容中將自動完成功能中的設置.
也能夠在form標籤中經過設置autocomplete爲"on"或者"off"來開啓或關閉自動完成功能.
a標籤的四個僞類分別是未訪問link,已訪問visited,鼠標懸停hover,鼠標點擊瞬間active
四個僞類的順序是:分別是link,visited,hover,active.
其實link和visited的順序實際上是無所謂的,由於不可能同時觸發未訪問和已訪問.
可是link是必定要在hover或者active以前.
visited要在hover以前.
而hover要在active以前.
關於兼容性的話,必需要在ie8包含ie8以上纔有用.
第一點多是由於沒有設置HTML編碼,也就是沒有在meta標籤中設置charset屬性.
第二點也多是使用了記事本編輯html,直接使用記事本編輯很容易形成html編碼亂碼
能夠在meta標籤中設置charset屬性爲"utf-8",另外儘可能使用sublime等編輯器編輯代碼,而不是用記事本.
input的屬性目前在w3c上發佈的是有23種,像比較常見的有定義輸入字段的初始值value,規定輸入字段爲只讀的readonly,還有規定字段禁用的disabled.
另外還有一些給input限制的標籤,好比像size規定字段的尺寸,maxlength規定輸入字段容許的最大長度
在咱們H5中有給input添加了不少的屬性,好比規定form自動完成功能的autocomplete,自動獲取焦點的autofocus.
還有max和min規定元素的最大最小值等等.
倆個都是表單的屬性,都能作到使用戶不能更改表單域中的內容.但他們也有一些差異.
第一點:readonly只針對type爲text,password,textarea有效,而disabled對全部的表單元素都有效.
第二點:readonly能夠進行表單提交,而disabled不能.
首先在樣式上,當type爲text的時候,在ie瀏覽器下和在火狐等瀏覽器下高度不一樣,ie下爲24px,火狐下爲22px
type爲submit也會不一樣.
同時在低版本的ie瀏覽器(ie8如下)下,input中的文本內容都會偏上一點.解決方案是給其添加padding-top.也能夠給其設置高度和行高相等,可是在火狐下不行.
type爲button時,value不能爲空,不然它就不會和其餘的表單元素頭部對其,而是向上一些.解決方案:最後不要給value爲空.
經常使用的內聯塊元素有img標籤,input標籤
首先內聯塊元素是和塊元素同樣能夠設置寬高的,可是卻能夠像內聯元素同樣放在同一行顯示,代碼空格換行也會被解析.
那是由於內聯元素的空格和換行會被解析
解決方案能夠手動將回車空格給去除,可是這樣會影響代碼的美觀,因此若是是像img這種不須要文本內容的內聯塊元素能夠給它的父級的font-size設爲0,也能夠將它的寬高都設爲100%.
對於咱們前端的網頁優化來講,一方面是提升咱們頁面的加載速度,還一方面可能就是提升咱們頁面的表現性.
對於提升頁面加載速度能夠有這麼幾種方式:
1.減少Http請求的數量.
2.還能夠運用css sprites技術將多個圖片融合在一張大圖上,另外也能夠對圖片進行壓縮,好比png圖片在www.tinypng.com上面進行壓縮,而後在webpack進行轉base64,只有圖片大小不超過10k纔會轉.
3.使用CDN;
4.添加Expires頭;
5.將樣式表放在頭部,減小頁面首屏出現的時間,使內容逐步呈現,提升用戶體驗,能夠防止"白屏"
6.將腳本放在底部,也是和樣式表放在頭部同樣.由於js的下載會中斷DOM的更新,因此script標籤要是放在首屏範圍內的HTML代碼裏是會截斷首屏的內容的.另外也是爲了保證腳本能按順序執行.
7.避免css表達式
8.使用外部的javascript和css,由於當腳本或者css是從外部引用進來的時候,瀏覽器就有可能緩存它,在之後加載的時候就能夠直接使用緩存.
9.減小DNS查找.
10.精簡代碼.
11.避免重定向.由於當頁面發生了重定向的時候,就會影響整個HTML文檔的傳輸.
12.使AJAX可緩存,也就是多用get而少用post,由於get是會在客戶端進行緩存的,而post不會.
CDN實際就是一組分佈在不一樣地理位置的Web服務器,能夠更加有效的像用戶發佈內容.
CDN還能夠進行數據備份,擴展存儲能力,進行緩存.
同時也是有一些缺點的,好比響應時間是會受到其餘網站流量的影響,而且若是CDN服務質量降低了,你的工做質量也會降低,同時它也沒法控制組件服務器.
當咱們初次訪問一個頁面的時候,是會進行不少HTTP請求的,可是經過使用一個長久的Epires頭,就可使這些組件被緩存下來,下次訪問的時候就能夠減小沒必要要的HTTP請求.
相同點:
都實現了根據本身的條件實現的頁面的跳轉
區別:
重定向致使瀏覽器發出了新的請求,在重定向以前存儲爲請求屬性的任何對象都會消失,因此跳轉到應用內的某個頁面,沒有瀏覽記錄,而打開新頁面不會這也是二者最大的區別.
因此使用重定向後,返回按鈕會失效,除非在設置返回按鈕時給它一個指定的路徑.
爲了提升網頁的性能,應該避免重定向.
重定向是用戶從一個URL從新路由到另外一個URL.經常使用的重定向的類型有永久重定向,臨時重定向.
永久重定向用於當網站的域名發生變動後,應該告訴搜索引擎域名已經變動了,從而不影響網站的排行.
而臨時重定向主要是實現post請求以後告知瀏覽器轉移到新的url,
應用的場景主要是
1.跟蹤內部流量
2.跟蹤出站流量
由於咱們知道重定向其實就是用戶從一個URL從新路由到另外一個URL,因此就使瀏覽器發出了一個新的請求,這樣是會延遲整個HTML文檔的傳輸
在介紹data-
屬性的做用以前我想先介紹一下data-
,
data-屬性是H5才新增的一種自定義屬性,這些屬性集能夠經過對象的dataset屬性獲取,不支持該屬性的瀏覽器能夠經過 getAttribute方法獲取
在兼容性上
,dataset屬性只有在IE11以上,Chrome8+瀏覽器中實現,因此在此期間最好用的getAttribute和setAttribute來操做。
爲何使用它呢,咱們知道HTML標籤是能夠經過自定義屬性來存儲和操做數據的,可是這樣在寫法上就不太符合Html的規範,因此H5新添了這個自定義屬性data
js中獲取設置data-屬性:
<div id = "user" data-uid = "12345" data-uname = "王先生" > </div>
<script>
var user = document.getElementById('user');
// 1. data屬性可以直接用getAttribute獲取,但那樣就失去了它的意義,因此不推薦使用
var userName = user.getAttribute('data-uname');
var userId = user.getAttribute('data-uid');
console.log(userName); // "王先生"
// 設置的話能夠用setAttribute();
user.setAttribute('data-site', 'www.baidu.com');
console.log(user.dataset.site); // www.baidu.com
// 2. 定義了data-的屬性應該用dataset來獲取,獲取的是整個含有data屬性的對象
var dataSet = user.dataset
console.log(dataSet);// {uid:"12345",uname:"王先生"}
// 這樣咱們就能夠用dataset來獲取裏面須要的data屬性
console.log(dataSet.uid); // "12345"
// 要修改的話就直接修改
dataSet.uname = "我是帥帥的王先生";
console.log(dataSet.uname);
// 使用in來判斷一個屬性是否是dataset中的屬性
console.log('someDataAtrr' in user.dataset); // false
console.log('uname' in user.dataset); // true
// // 刪除data屬性
delete user.dataset.uname; // 或者 user.dataset.user = null
console.log(user.dataset.uname);
// 選擇全部包含 'data-uid' 屬性的元素
var dataUids = document.querySelectorAll ('[data-uid]') ;
console.log(dataUids); // [div#user.users, div.users]
console.log(dataUids[0]); // <div class="users" id = "user" data-uid = "12345" data-uname = "王先生" >我是王先生</div>
</script>
複製代碼
CSS中獲取data-
<style>
.users[data-uid="12345"]{
color: red;
}
</style>
<div class="users" id = "user" data-uid = "12345" data-uname = "王先生" >我是王先生</div>
<div class="users" id = "user" data-uid = "54321" data-uname = "李先生" >我是李先生</div>
// 只有王先生變紅
複製代碼
在模式上,主要是有標準模式,和怪異模式。首先怪異模式ie下獨有的一種模式。它和咱們的標準模式主要是在佈局,樣式解析和腳本的執行上有一些差別吧。就好比在怪異模式下,盒模型是按照怪異盒模型解析的,咱們知道怪異盒模型和咱們普通盒模型的差異仍是很大的,另外,還有好比像在怪異模式下,咱們經常使用的margin:0 auto;這種居中方式就沒用了。
在css
中設置屬性
div {
box-sizing: border-box;/*怪異*/
box-sizing: content-box;/*標準*/
}
複製代碼
使用 window.top.document.compatMode
可顯示爲何模式
當頁面樣式加載失敗的時候可以讓頁面呈現出清晰的結構
有利於seo優化,利於被搜索引擎收錄(更便於搜索引擎的爬蟲程序來識別)
便於項目的開發及維護,使html代碼更具備可讀性,便於其餘設備解析。
什麼是BFC
BFC是塊級格式化上下文,是指在瀏覽器中建立了一個獨立的渲染區域,這個區域內的元素佈局不會影響到外面的元素,而且這個渲染區域只對塊級元素起做用,而後利用這些規則咱們能夠達到必定的佈局效果。
BFC的生成
float的值不爲none;
display爲inline-block table-ceil table-caption
overflow的值不爲visible
position的值爲absolute fixed
BFC的應用
防止margin重疊
解決了浮動的相關問題,由於建立了BFC的元素,子浮動元素也會參與其高度的計算,這樣就不會產生高度塌陷問題。
實現多欄佈局的一種方式,由於建立了BFC的元素,與浮動元素相鄰也不會和它互相覆蓋。好比能夠設置倆側寬度固定,中間元素隨頁面的寬度自適應。
a標籤不能嵌套a標籤(連接嵌套瀏覽器解析爲兄弟級關係)
p標籤不能嵌套塊級標籤 瀏覽器解析爲兄弟級關係
如若須要進行連接嵌套,能夠推薦使用area標籤
在之前是使用一些壓縮工具進行手動壓縮,可是如今咱們都是直接使用webpack打包工具.
在ie6是不支持border-radius的,當咱們要在ie6下想作一個圓角就可使用三層嵌套.可是在咱們實際的開發中,要是隻是爲了達到一個圓角的效果而使用各類圖片之類的有些太牽強了,因此在之前的開發中,我通常就是直接使用border-radius.
Page Visibility是H5新增的API
主要是用來判斷用戶是否是在與頁面進行交互,也就是好比頁面最小化了或者隱藏在其它標籤頁後面了,那麼此時就能夠用上咱們的這個頁面可見性.
這個API主要由三個部分組成:
第一個是document的hidden屬性,表示頁面是否隱藏的布爾值.
第二個是document的visibilityState屬性,它有四個可能狀態的值.
第三個是visibilitychange事件,當頁面的可見性發生改變時會觸發.
咱們能夠監聽document的visibilitychange事件,當該事件觸發時,獲取document.hidden的值來對頁面進行一些操做.好比隱藏頁面時讓播放的歌曲暫停等等.
頁面的隱藏包過頁面在後臺標籤頁中或者瀏覽器最小化,
而頁面被其餘軟件遮蓋不算是隱藏
visibilityState是判斷頁面狀態的一個屬性,有一下四個狀態的值:
在H5以前,咱們是靠監聽document獲取焦點和失去焦點來簡單的認爲頁面是隱藏仍是顯示的.
在css中,hack是指一種兼容css在不一樣瀏覽器中正確顯示的技巧.由於在不一樣的瀏覽器中,對css的解析認識不一樣,所以會致使生成的頁面效果不一樣.這時候咱們就須要針對不一樣的瀏覽器取寫對應的css樣式.一些常見的特殊符號的應用.
IE6認識的hacker 是下劃線 _ 和星號 *****
IE7能識別星號" * ",但不能識別下劃線"_",而firefox兩個都不能認識。
若是是塊元素的話給它設置inline-block沒有效果的,解決方案:
直接讓塊元素設置爲內聯對象呈現,也就是設置display: inline,而後在觸發塊元素的layout,好比設置zoom爲1等.
其餘的內聯元素好比a標籤,span標籤是能夠正常顯示的.
layout是ie的一個私有概念,它決定了一個元素如何顯示以及約束其包含的內容等等.一個元素是否具備"layot"屬性可能會致使不少問題,好比ie中不少常見的浮動bug,容器與它子孫元素的邊距重疊問題等等.
給元素設置浮動,設置絕對定位,設置寬高,設置zoom,以及轉換爲inline-block,或者設置overflow等等均可以觸發layout.
是ie中網頁縮放的比例
ie6/7下經過它來觸發元素的hasLayout,解決大部分ie瀏覽器下的兼容問題.好比能夠用來清除浮動,避免容器高度塌陷.
不過對於如今瀏覽器通常不必用它了,由於它只在ie瀏覽器下有用.
給父級float:left; 會影響後面的元素
給父級height:500px; 子級高度改變父級也要改變
給父級overflow:hidden;不一樣瀏覽器會有兼容性問題
給父級display:inline-block; 內聯塊的一堆問題還在 好比對齊之類的問題
給父級設置定位;
固然最好的辦法就是在浮動元素的父級元素上使用僞類:after在其後面加上一個空元素並清除它的浮動就能夠解決.
分別有3種不一樣深度的格式:png8,png24,png32
png8表示的是8位索引色位圖.png24就是24位索引色位圖
在使用場景上
,由於png8最多隻能顯示256種顏色,就更適合那些顏色比較單一的圖片,好比純色,logo,圖標等等.
而png24能顯示的顏色要比png8多的多,大概能有1600萬.
顯示效果上:
png8支持索引透明和alpha透明,而png24不支持透明,png32都支持.
在兼容性上
:咱們常常說的ie6下不支持PNG透明,指的是不支持png24的透明,可是支持png8的透明,就像支持gif同樣的透明同樣.也就是在ie6下png24的圖片的透明部分會被蒙上一層灰色.(解決方案
計算機顯示的圖片中所使用的顏色,均有一個顏色體系,每個顏色與一個顏色表對應出來,索引色常使用16色.32色等,最多不超過256色.
1.色彩豐富的,大的圖片切爲gif;
2.尺寸小,並且色彩不是很豐富和背景透明的切成gif或者png8;
3.而半透明的切爲png24
好比左側圖片大小固定,右側隨父級寬度改變而改變
1.使用定位.
2.父級設定高度,子級高度100%,左側圖片大小固定並給左浮,右側元素寬度給100%,由於左側浮動了是壓得住屬性壓不住內容的,因此若是有什麼文字內容的是會環繞在圖片周圍,可是最好仍是加一個margin-left,以免右側有背景圖會被覆蓋.
3.利用彈性佈局,父級設定display: flex;左側圖片大小固定,右側元素設定flex爲1.
第一種狀況:已知元素的寬高
將元素設置定位absolute或者fixed,top和left爲50%,margin-left和margin-top爲負的寬高的一半。
將元素設置定位absolute或者fixed,top和left爲50%,transform: translate()爲負的寬高的一半或者-50%。
第二種狀況:不知元素的寬高
將元素設置定位,四個方向定位都爲0,而後設定margin: auto;
若是子元素是內聯元素或者內聯塊元素也能夠將父元素設定:(使圖片居中最快的方式)
display: table-ceil;
text-align: center;
vertical-align: middle;
複製代碼
第三種狀況:一個瀏覽器頁面中,只有一個div模塊,讓其上下左右居中
將元素設置定位absolute或者fixed,top和left爲50%,margin爲auto。
###10.響應式佈局是什麼?
響應式佈局就是界面可以適應不一樣的設備,不一樣的屏幕大小,讓同一個頁面在在不一樣的大小比例裏看上去仍是溫馨的,不一樣分辨率上看上去仍是合理的,不一樣的操做方式體驗應該是統一的.
####用本身的話描述一下對「異步「和」同步「的理解
對「異步」和「同步」我是這樣理解的,首先,咱們知道JS是一門單線程語言,也就是不能同時進行不少的事。
全部的任務都得排隊,要前一個任務完成以後才能執行下一個任務。但若是咱們的任務列表中有像定時器,ajax請求這一類耗時程序的時候,不得不等結果出來以後再往下執行。因此這時候咱們的JS就想到能夠將這些耗時耗性能的任務提取出來而後先無論它們讓他們處於等待狀態,等那些不耗時的任務執行完以後再來執行這些耗時的任務。
因此像前面我說的那些不耗時的任務的就是==同步任務==,盛放他們的列表就是==主線程==。而另外一些就是==異步任務==,它們天然是不在主線程中的,而是在==任務隊列==。因此只要主線程空了,就會去讀取"任務隊列"。
第一種是異步編程最基本的方法,採用==回調函數==的方式,將不耗時的任務或者說是函數做爲耗時的函數的回調函數,這種方式的優勢是簡單,容易理解和部署,缺點是不利於代碼的閱讀和維護,各個部分之間高度耦合,流程會很混亂,而且每一個任務只能指定一個回調函數。
另外一種思路是採用==事件驅動==的方式,任務的執行不是取決於代碼的順序,而是取決於某個事件是否發生,這種方法的優勢是比較容易理解,能夠綁定多個事件,而且每一個事件均可以指定多個回調函數,去除了耦合,有利於實現模塊化。缺點是整個程序都變成了事件驅動,運行流程會變得不清晰。
第三種能夠採用==發佈/訂閱==的方式,或者說是觀察者模式,這種方法的性質與"事件監聽"相似,可是明顯優於後者。由於咱們能夠經過查看"消息中心",瞭解存在多少信號、每一個信號有多少訂閱者,從而監控程序的運行。
最後一種就是咱們ES6的==promise==對象,它是CommonJS工做組提出的一種規範,目的是爲異步編程提供統一接口。簡單說,它的思想是,每個異步請求都會返回一個Promise對象,該對象會有一個then方法,容許指定回調函數。它的優勢在於回調函數變成了鏈式寫法,程序的流程能夠看到很清楚,而且也有一整套配套的方法,實現不少強大的功能,好比指定多個回調函數,指定發生錯誤時候的回調函數fail等等。而且它也有其餘三個方法沒有的一點就是若是一個任務已經 完成了,再添加回調函數,這個回調函數是會當即執行的,這樣就不用擔憂是否錯過了某個事件或信號。它的缺點就是有些難理解。
首先http是一個基於請求與響應模式的、無狀態的、應用層的協議
咱們的http協議主要包括了2部分,一部分是==請求協議==,也就是瀏覽器向服務器端發送請求的時候,還有一個是==響應協議==,也就是服務器向瀏覽器響應的時候。
嗯,同源策略是瀏覽器的一個安全機制,爲了保護用戶的信息安全,防止惡意的網站竊取數據,也就是一個url的協議,域名,端口號三個都相同狀況下,才被判斷爲同源。
它最初也就是使用在不一樣源的狀況下不能讀取其餘網站的Cookie,可是隨着互聯網的發展,同源策略也變得愈來愈嚴格,目前的話,若是非同源的狀況下,不只像Cookie、Localstorage這種本地儲存不能獲取,連DOM也不能獲取,同時也不能發Ajax請求。
雖然它有它的好處可以保護用戶信息安全,但有時也是挺不方便的。
第一種:
好比咱們知道cookie是服務器寫入瀏覽器的一小段信息,只有同源的網頁才能共享,可是當倆個網頁一級域名相同,只是二級域名不一樣的狀況下,咱們也想共享這個cookie。這時就能夠經過設置相同的document.domain來共享cookie,也能夠在服務器設置cookie的時候,指定cookie的所屬域名爲一級域名(Set-Cookie: domain=.example.com),這樣二級,三級域名不用作任何的處理也能讀取到這個cookie。
第二種:
還有一些請求是像iframe窗口和window.open方法打開新窗口的時候,若是打開的這個窗口與父窗口不一樣源的時候,是不能與父窗口進行通信。也就是對於徹底不一樣源的網站,想解決這種跨域的窗口通信問題,該怎麼辦。
目前其實也是有三種解決方案的。
1.第一種是利用片斷標識符,咱們知道片斷標識符指的就是URL的#後面的部分,改變這個片斷標識符是不會從新刷新的,這樣父窗口就能夠把信息寫入子窗口的片斷標識符中。
2.第二種是利用window.name屬性,由於咱們知道這個屬性最大的特色就是不管是否同源,只要在同一個窗口,前一個頁面設置了這個屬性,後面一個網頁也能讀取到它。它的優勢就是window.name容量很大,能夠存儲很是常的字符串,缺點是要監聽子窗口的window.name,這樣就影響了網頁的性能。
3.固然,咱們H5爲了解決這個問題,就引入了一個全新的跨文本通訊的API.這個API爲window對象新增了一個window.postMessage方法,容許倆窗口通訊,不管這倆個窗口是否同源。這樣就也能夠獲取LocalStorage和cookie了。
可是在有src屬性的標籤是不受同源策略的影響的,好比咱們的img、script、ifame、link標籤。
原理:
jsonp的優勢是:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制,同時兼容性也更好,在更加古老的瀏覽器中均可以運行,不須要XMLHttpRequest或者ActiveX的支持,而且在請求完畢以後能夠經過一個回調函數callback的方式回傳結果。
同時它也有一些缺點,首先它只支持get請求而不支持post等其餘類型的HTTP請求,另外它只支持跨域HTTP請求這種狀況,不能解決不一樣域的倆個頁面之間如何進行JavaScript調用的問題。
http狀態碼由三位數字組成,第一位表示的是一個大狀態,後面兩個數字表示該大狀態的一個子狀態。
好比200就是請求成功,3開頭的表示重定向,4開頭的狀態碼客戶端出錯,5開頭的是服務器錯誤。
又好比常見的404資源未找到,403被請求的頁面禁止訪問等等。
實體連接網絡傳輸應用
首先,TCP協議是以太網協議和IP協議的上層協議,也是應用層的下層協議。
它的做用呢,簡單來講就是爲了保證數據通訊的完整性和可靠性,防止丟包。
以太網協議
最底層的以太網協議(Ethernet)規定了電子信號如何組成數據包(packet),解決了子網內部的點對點通訊。
IP協議
IP協議的做用有兩個:
1·爲每臺計算機分配IP地址,
2.肯定哪些地址是在同一個子網絡。
解決的就是多個局域網互相通訊,好比路由器就是基於IP協議的。
ARP協議
IP數據包是放在以太網數據包中的,因此咱們必須知道倆個地址,一個是對方的IP地址,一個是MAC地址。
獲取MAC地址的倆種狀況:
一、倆臺主機不在一個子網絡,將數據包交給「網關」,讓「網關」處理。
二、倆臺主機在一個子網絡中,利用==ARP協議==獲取同一個子網絡中的主機的MAC地址。
###3.AJAX
ajax的原理簡單來講其實就是經過==XMLHttpRequest==對象來向服務器發異步請求,從服務器獲取數據。而這個XMLHttpRequest就是咱們Ajax的核心機制,它是在ie5中首先引入的,是一種支持異步請求的技術,簡單來講,就是javascript可以及時向服務器請求和處理響應,而不阻塞用戶,達到無刷新的效果。
大體流程就是建立一個==XMLHttpRequest對象==,而後調用這個對象的==open==方法來指向請求的類型,有get方式或者是post方式來鏈接服務器,接着可使用==send==來發送請求,同時能夠用==onreadystatuschange==來監聽請求的狀態。如果成功獲取到數據的話再用回調函數拿到數據。
能夠看到Ajax的==優勢==也很明顯,最大的一點就是頁面無刷新,給用戶的體驗很是好,同時也可使用異步的方式,提升響應能力,減輕了服務器的負擔,進一步促進頁面和數據的分離。
但同時它也是有一些缺點的,並且這些缺點也是它先天產生的。首先它幹掉了==back==按鈕,即對瀏覽器後退機制的破壞。還有一點就是==安全問題==,可能開發者在不經意間就暴露了比之前更多的數據和服務器邏輯。另外他它對==搜索引擎==的支持也比較弱
首先,咱們知道同源策略規定了,Ajax的請求只能發給同源的網址,不然就會報錯。
除了設置==代理服務器==,還有三種方式來規避這種限制。
第一種也就是咱們經常使用的方法==jsonp==,它最大的優勢就是簡單適用,老式的瀏覽器也全都能用。
第二種呢就是能夠利用==WebSocket==這種通訊協議。
第三種可使用==CORS==,它比jsonp要更強大一些,由於jsonp是隻支持GET請求的,而它卻支持全部類型的HTTP請求。可是咱們知道CORS他的兼容性不是很好,一些老牌瀏覽器像IE10如下的它就不支持。
####1.ajax的事件?
ajaxComplete(callback)
ajaxError(callback)
ajaxSend(callback)
ajaxStart(callback)
ajaxStop(callback)
ajaxSuccess(callback)
是最先期爲了取代ajax把數據拿來而後渲染到頁面上,在性能上也沒有作任何的優化,常常看到的模板引擎好比==Mustache、Underscore、 Templates==等等。但隨着像React Angular 以及最近比較火的Vue的出現,能夠說徹底的被取代了。並且這些前端框架作到的不只僅是它能作到的,同時在性能上優化了不少,功能上也更加的強大。
老點的有phoneGap
app和webapp區別
app是能夠點擊安裝的,是基於操做系統,webapp是基於瀏覽器的
咱們知道,在咱們JS中是沒有塊級做用域的,js文件與js文件之間定義的變量也是能夠互相訪問的,這樣在咱們開發中就很容易形成命名衝突從而引發咱們程序的一系列異常。
但要知道若是在函數內部定義一個變量的話這個變量就只有在其內部能訪問到也就是咱們常說的局部變量了,那麼OK,若是咱們用一個外部的函數將一個內部函數包裹起來,那麼如今若是在外部函數裏定義一個變量,這個變量就只有這個外部函數和它裏面的內部函數可以訪問到。
主要是爲了設計私有的方法和變量。它的優勢也很明顯,能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。
因此它主要是有這三個特性:
1.函數嵌套函數 2.函數內部能夠引用外部的參數和變量 3.參數和變量不會被垃圾回收機制回收
首先咱們js裏是沒有真正像其它面嚮對象語言同樣概念的繼承,js中的繼承都是模擬繼承。
像咱們常見的繼承方式有:
第一種,能夠採用構造函數綁定的方式,就是使用apply、call來借調要繼承的那個父對象的構造函數。
第二種,能夠利用prototype屬性來實現繼承,能夠將要繼承的那個子構造函數的原型對象指向父構造函數建立出來的實例對象。可是這種方式會致使繼承鏈的紊亂。
第三種,第三種方式是第二種方式的一種改進吧,就是直接將要繼承的那個子構造函數的原型對象指向父構造函數
的原型對象。它相比於第二種效率要高點,可是因爲如今倆個構造函數的原型對象指向的都是同一個,因此若是更改任意一個原型對象中的屬性的話都會映射到另外一個函數中。
因此能夠有第四種改進方案,利用一個空對象來做爲中介。建立一個空對象而後這空對象中是一個函數,咱們將這個空對象的原型對象指向父構造函數的原型對象,接下來用這個空的構造函數建立一個實例對象,再將子構造函數的原型對象指向它,實現了繼承。
第五種咱們能夠採用拷貝的方式來實現繼承。拷貝的話又分深拷貝和淺拷貝。
咱們知道js中數據類型是分爲基本數據類型和引用數據類型,這些基本數據類型是能夠直接訪問的,它們是存放在咱們棧內存中,而咱們的引用數據就是那些存儲在堆內存中的對象。
因此其實當咱們進行將一個對象賦值給另外一個對象的過程實際只是將整個對象的地址傳遞給了,此時它們倆指向的都是同一個地址,這樣若是我改變其中一個對象中的屬性的話是也會影響另外一個對象的,這也就是咱們說的淺拷貝。
那麼深拷貝呢,它就是解決了上面那種狀況,是將父對象拷貝到子對象中,並且倆者的內存和之後的操做都互不干擾。
Object.assign()
{ ...object }
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj === "object") {
for(key in obj) {
if(obj.hasOwnProperty(key)) {
// 判斷 obj 子元素是否爲對象,若是是,遞歸複製
if(obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
// 若是不是,簡單複製
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a = [1, 2, 3, 4];
let b = deepClone(a);
a[0] = 2;
console.log(a, b);
// Console
// a = [2, 2, 3, 4];
// b = [1, 2, 3, 4];
複製代碼
該方法實際就是經過typeof
判斷如下對象中屬性的類型是否是object
,若是是的話則在進行接下去的判斷。(這裏就直接借鑑jsliang小夥的寫法了)
固然你也能夠採用JSON.parse(JSON.stringify(obj))
的方式來進行拷貝,可是這種拷貝是存在兼容問題的,由於咱們只這倆種方法是隻有在ie8以上才支持的,而且它不支持拷貝值爲function
、symbol
和undefined
的屬性。
console.log(Number(null));
console.log(parseInt(null));
console.log(typeof null);
console.log(Number(undefined));
console.log(parseInt(undefined));
console.log(typeof undefined);
demo.html:14 0
demo.html:15 NaN
demo.html:16 object
demo.html:18 NaN
demo.html:19 NaN
demo.html:20 undefined
複製代碼
TypeScript 與JavaScript二者的特性對比,主要表現爲如下幾點:
.then
代碼塊中設置斷點,點擊下一步調試器不會跳到下一個.then
而是直接跳過異步代碼。想了解具體區別的小夥能夠移步:async/await比promise好的緣由
var drawing = document.querySelector('#drawing');
if (drawing.getContext) {
var context = drawing.getContext("2d");
context.beginPath();
}
複製代碼
var drawing = document.querySelector('#drawing');
if (drawing.getContext) {
var context = drawing.getContext("2d");
// 繪製外圓
context.beginPath();
context.arc(100, 100, 99, 0, 2 * Math.PI, false);
// 內圓
context.moveTo(194, 100);
context.arc(100, 100, 94, 0, 2 * Math.PI, false);
// 變換原點
context.translate(100, 100);
// 旋轉錶針
context.rotate(1);
context.moveTo(0, 0);
context.lineTo(0, -85);
context.moveTo(0, 0);
context.lineTo(-65, 0);
context.stroke();
}
複製代碼
let imageData = context.getImageData(0, 0, image.width, image.height);
複製代碼
我理解的生命週期是,每個vue實例被建立以前都要通過一系列 的初始化過程。好比須要設置數據監聽,編譯模板,還有數據變化時更新DOM等等。同時在這個過程當中,就會運行一些就叫作生命週期鉤子的函數,用來給予用戶在一些特定的場景下添加代碼。
主要分爲如下8種:
建立前/後:在 beforeCreated 階段,Vue 實例的掛載元素 $el
和數據對象 data 以及事件還未初始化。在 created 階段,Vue 實例的數據對象 data 以及方法的運算有了,$el
尚未。
載入前/後:在 beforeMount 階段,render
函數首次被調用,Vue 實例的 $el 和 data 都初始化了,但仍是掛載在虛擬的 DOM 節點上。在 mounted 階段,Vue 實例掛載到實際的 DOM 操做完成,通常在該過程進行 Ajax 交互。
更新前/後:在數據更新以前調用,即發生在虛擬 DOM 從新渲染和打補丁以前,調用 beforeUpdate。在虛擬 DOM 從新渲染和打補丁以後,會觸發 updated 方法。
銷燬前/後:在執行實例銷燬以前調用 beforeDestory,此時實例仍然能夠調用。在執行 destroy 方法後,對 data 的改變不會再觸發周期函數,說明此時 Vue 實例已經解除了事件監聽以及和 DOM 的綁定,可是 DOM 結構依然存在。
會觸發 4 個生命鉤子:建立前/建立後、掛載前/掛載後。
我對slot的理解就是當組件中的某一項須要單獨定義的時候,那麼就應該使用slot。
好比說在一個模態框中,付款成功和付款失敗,這個模態框僅僅是差了一個字或者是圖片不同,
那麼這個時候利用slot就會是不錯的選擇。
單個的slot都沒有問題,若是組件中想要使用多個slot的時候就應該使用具名slot。具名slot呢也就是使用一個特殊的特性name來進一步配置如何分發內容。咱們能夠在組件中定義slot的時候給一個name屬性,而後在調用組件時候在匹配內容內用slot屬性來匹配對應的name。同時它也容許有一個匿名的slot,也就是默認插槽,它是做爲找不到匹配內容片斷的備用插槽,如果沒有這個默認插槽的話,那麼這些內容片斷就會被拋棄。
vue是經過數據劫持的方式來進行雙向數據綁定的,最核心的方法就是ES5的Object.defineProperty()方法,使用getter/setter監測對數據的操做。
它的操做呢大體能夠分爲三步:
第一步:利用get實現一個數據監聽器,對數據對象的全部屬性進行監聽。
第二步:實現一個指令解析器,對全部元素的節點指令進行解析。
第三步:實現一個觀察者,可以訂閱並收到每一個屬性變化的通知,而後執行相應的回調函數,從而更新視圖。
相同點:
不一樣點:
實現雙向數據綁定的原理不一樣:Angular實現雙向數據綁定主要是依賴於髒值監測,也就是存儲舊數值,而後在檢測時把當前時刻的新值和舊值進行比對來達到是否更新視圖的效果;而在vue中,採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。
vue須要提供一個el對象進行實例化,後續的全部做用範圍也是在el對象之下,而angular而是整個html頁面。一個頁面,能夠有多個vue實例,而angular好像不是這麼玩的。
知識產權無價,支持原創。
內容也會同步更新自個人我的博客:lindaidai.wang
參考文章: