三欄佈局
- float
<div> <section class="a1">a1</section> <section class="a2">a2</section> <section class="a3">a3</section> <section class="a4">a4</section> <section class="a5">a5</section> </div> div { width: 180px; height: 50px; } section { float: left; } .a1 { width: 50px; height: 50px; background-color: tan; } .a2 { float: right; width: 50px; height: 50px; background-color: tan; } .a3 { width: 80px; height: 25px; background-color: red; } .a4 { width: 40px; height: 25px; background-color: #ddd; } .a5 { width: 40px; height: 25px; background-color: #666; } 複製程式碼
- position
div { width: 180px; height: 50px; position: relative; } .a1 { position: absolute; width: 50px; height: 50px; background-color: red; } .a2 { position: absolute; left: 50px; width: 80px; height: 25px; background-color: blue; } .a3 { position: absolute; left: 50px; top: 25px; width: 40px; height: 25px; background-color: green; } .a4 { position: absolute; left: 90px; top: 25px; width: 40px; height: 25px; background-color: tan; } .a5 { position: absolute; width: 50px; height: 50px; left: 130px; background-color: red; } 複製程式碼
- flex
div {
width: 180px;
height: 50px;
display: flex;
flex-flow: column wrap;
align-content: flex-start;
}
.a1 {
width: 50px;
height: 50px;
background-color: red;
}
.a2 {
width: 80px;
height: 25px;
background-color: tan;
}
.a3 {
flex-grow: 1;
background-color: aqua;
}
.a4 {
width: 25px;
height: 50px;
background-color: #fff;
}
.a5 {
flex-grow: 1;
background-color: red;
}
複製程式碼
- 三欄等寬佈局
div {
width: 180px;
height: 50px;
display: flex;
background-color: tan;
}
section {
flex: auto;
}
.a1 {
background-color: #fff;
}
.a2 {
background-color: #444;
}
.a3 {
background-color: red;
}
複製程式碼
垂直居中
- position
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
複製程式碼
- table
div {
width: 100px;
height: 100px;
position: relative;
background-color: tan;
display: table-cell;
vertical-align: middle;
text-align: center;
}
span {
background-color: red;
}
複製程式碼
- 行內塊
div {
width: 100px;
height: 100px;
position: relative;
background-color: tan;
}
section {
width: 50px;
height: 50px;
display: inline-block;
margin: 25px;
background-color: red;
}
複製程式碼
- float
div {
width: 100px;
height: 100px;
position: relative;
background-color: tan;
}
section {
width: 50px;
height: 50px;
margin: 25px;
float: left;
background-color: red;
}
複製程式碼
- line-height
div {
width: 100px;
height: 100px;
background-color: tan;
text-align: center;
line-height: 100px;
}
span{
background-color: #fff;
vertical-align: middle;
}
複製程式碼
盒模型
margin-box, border-box, padding-box, content-box
首先是最內層content-box,用來顯示元素資訊
向外是padding-box,主要用於設定元素四個方向的內邊距,
再向外是border-box,用於設定元素四個方向的邊框樣式,
最外層是margin-box,為了讓元素與其他元素隔開,對於垂直方向上的BFC元素的margin會發生合併,去較大的值
padding-box和margin-box是透明的,padding-box會受元素的背景的影響,可以通過box-sizing設定
padding-box和border-box不能去負值,margin-box可以取負值
還有元素的溢位屬性,處理空白空間及文字溢位
* css中每個元素都看作多個盒子的組合,我們可以通過設定這些盒子的屬性來改變元素的樣式
* 如果設定 box-sizing 為 content-box,那麼寬度就是內容區的寬度
* 如果設定為 border-box,那麼寬度就死活內容區寬度+padding+border
複製程式碼
單行文字溢位省略:
text-overflow:ellipsis; white-space:nowrap; overflow:hidden;
BFC
浮動,絕對定位,overflow不為visible,非塊級盒子塊級容器
觸發:
1. float 除了none以外的值
 2. overflow 除了visible 以外的值(hidden,auto,scroll )
 3. display (table-cell,table-caption,inline-block, flex, inline-flex)
 4. position值為(absolute,fixed)
特性:
在BFC中,盒子從頂端開始垂直地一個接一個地排列。
盒子垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰盒子垂直方向的margin會發生重疊。
在BFC中,每一個盒子的左外邊距(margin-left)會觸碰到容器的左外邊緣(border-left)。
BFC不會與浮動盒子產生交集,而是緊貼浮動元素邊緣。
計算BFC高度BFC時,自然也會檢測浮動的子盒子高度。
應用:
自適應兩欄佈局
解決margin疊加問題:下面元素新增父元素:overflow: hidden;
清除浮動,計算BFC高度
複製程式碼
閉合浮動的辦法:
- 包含塊overflow:hidden/BFC
- 包含塊display:flow-root/BFC
- 包含塊變表格/BFC
- 包含塊變行內塊元素/BFC
- br標籤的清除浮動
談談你對MVVM開發模式的理解
- MVVM主要分為model/view/viewmodel三部分
- model:代表資料模型,資料和業務邏輯都在model層中定義
- view:代表UI檢視,負責資料的展示
- viewmodel:負責監聽model中資料的改變並且控制檢視的更新,處理使用者互動操作
- Model和View並無直接關聯,是通過viewmodel來進行聯絡的,model和viewmodel之間有著雙向資料繫結的聯絡。因此當model中的資料改變時會觸發view層的重新整理,同樣view中由使用者互動操作而改變的資料也會在model中同步。
- 這種模式實現了model和view的資料自動同步,因此開發者只需要專注於對資料的維護操作即可,而不需要自己操作DOM
如何優化SPA應用的首屏載入速度慢的問題
- 將公用的JS庫通過script標籤外部引入,讓瀏覽器並行下載資原始檔,提高下載速度;
- 在配置路由時,頁面和元件使用懶載入的方式引入,在呼叫某個元件時再載入對應的js檔案;
- 加一個首屏 loading 圖,提升使用者體驗;
跨域(Cross-Origin)
只要協議、主機、埠不一致,就會有跨域的問題
- javascript跨域通訊
- jsonp
- CORS設定跨域頭
- 在框架中配置跨域代理
- jsonp的實現原理
- script標籤引入外部網站的程式碼,一般都是使用查詢字串告訴對方我們頁面中的callback函式,然後對方把需要返回的資料包在這個函式裡面
- 其實JSONP並不算真正意義上的AJAX請求,只是請求了一個js檔案並且執行了,而且這種跨域方法只能進行GET請求
function jsonp(url, value, cb) {
let cbName = 'JSONP_CALLBACK_' + Date.now() + '_' + Math.random().toString().slice(2)
window[cbName] = cb
url = url + '?q=' + value + '&callback=' + cbName
let script = document.createElement('script')
script.src = url
script.onload = () => {
document.body.removeChild(script)
delete window[cbName]
}
document.body.appendChild(script)
}
function ajax(url = '', data = {}, type = 'GET') {
if (type === "GET") {
let urlStr = ""
Object.keys(data).forEach(key => {
urlStr += key + '=' + data[key] + '&'
})
if (urlStr) {
urlStr = urlStr.substring(0, urlStr.length - 1)
url += '?' + urlStr
}
return axios.get(url)
} else if (type === "POST") {
return axios.post(url, data)
}
}
複製程式碼
- CORS
- 它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制
- 簡單請求
- 請求方法為HEAD、GET或者POST中的一種
- HTTP的頭資訊有以下幾種欄位Accept、Accept-Language、Content-Language、Last-Event-ID
- Content-Type的值只限於application/x-www-form-urlencoded、multipart/form-data、text/plain三個
- 瀏覽器發出請求時,瀏覽器會自動在請求頭中新增一個欄位Origin,值為發出請求網頁的源地址
- 服務端根據這個值,決定是否同意這次請求,如果Origin的值不在指定的許可範圍,瀏覽器接收到的HTTP回應將不包含Access-Control-Allow-Origin,丟擲錯誤被XMLHttpRequest的onerror回撥函式捕獲。如果Access-Control-Allow-Origin欄位正好跟帶過去的Origin的值一樣,則返回對應的資料,完成一次請求。
- 非簡單請求以及option請求
- 非簡單請求是那種對伺服器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type欄位的型別是application/json。
- 在進行非簡單請求之前,瀏覽器會在正式請求之前傳送一次預檢請求,這就是有時候我們會在控制檯中看到的option請求,就是說,正式請求之前,瀏覽器會去問服務端我這個地址能不能訪問你,如果可以,瀏覽器才會傳送正式的請求,否則報錯。
- 總結
- CORS實現跨域的方法就是根據請求頭的Origin值和響應頭的Access-Control-Request-Headers和Access-Control-Request-Method的值進行比對,通過了就可以請求成功,沒通過就請求失敗。
- 比較
- JSONP只支援GET請求,CORS支援所有型別的HTTP請求。JSONP的優勢在於支援老式瀏覽器,以及可以向不支援CORS的網站請求資料。
前端如何優化網站效能
- 減少 HTTP 請求數量:
- 瀏覽器與伺服器主要是通過 HTTP 進行通訊。瀏覽器與伺服器需要經過三次握手,每次握手需要花費大量時間。而且不同瀏覽器對資原始檔併發請求數量有限,一旦 HTTP 請求數量達到一定數量,資源請求就存在等待狀態,因此減少 HTTP 的請求數量可以很大程度上對網站效能進行優化。
- CSS Sprites:
- 國內俗稱 CSS 精靈,這是將多張圖片合併成一張圖片達到減少 HTTP 請求的一種解決方案,可以通過 CSS background 屬性來訪問圖片內容。這種方案同時還可以減少圖片總位元組數。
- 合併 CSS 和 JS 檔案:
- 現在前端有很多工程化打包工具,如:grunt、gulp、webpack等。為了減少 HTTP 請求數量,可以通過這些工具再發布前將多個 CSS 或者 多個 JS 合併成一個檔案。
- 採用 lazyLoad:
- 俗稱懶載入,可以控制網頁上的內容在一開始無需載入,不需要發請求,等到使用者操作真正需要的時候立即載入出內容。這樣就控制了網頁資源一次性請求數量。
- 利用瀏覽器快取
- 瀏覽器快取是將網路資源儲存在本地,等待下次請求該資源時,如果資源已經存在就不需要到伺服器重新請求該資源,直接在本地讀取該資源。
- 減少 DOM 操作,達到減少重排(Reflow)
- 基本原理:重排是 DOM 的變化影響到了元素的幾何屬性(寬和高),瀏覽器會重新計算元素的幾何屬性,會使渲染樹中受到影響的部分失效,瀏覽器會驗證 DOM 樹上的所有其它結點的 visibility 屬性,這也是 Reflow 低效的原因。如果 Reflow 的過於頻繁,CPU 使用率就會急劇上升。
Less / Sass
Less的變數名使用@符號開始 Sass的變數是必須$開始
- 作用域:
- Sass無全域性變數概念
- LESS中的作用域和其他程式語言中的作用域非常的相同
- 混合(Mixins):
- Sass
宣告:@mixin a($borderWidth:2px){} 呼叫:@include error(); 複製程式碼
- Less
宣告:.error(@borderWidth:2px){} 呼叫:.error(); 複製程式碼
- 繼承
- Sass
@extend .block; /*繼承.block選擇器下所有樣式*/ 複製程式碼
- Less
.block;/*繼承.block選擇器下所有樣式*/ 複製程式碼
AntDesign / bootstrap
http協議
- HTTP是基於TCP/IP通訊協議來傳遞資料
- HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端伺服器模型。HTTP是一個無狀態的協議。
- 工作過程大概如下:
- 使用者在瀏覽器中鍵入需要訪問網頁的URL或者點選某個網頁中連結;
- 瀏覽器根據URL中的域名,通過DNS解析出目標網頁的IP地址;
- 在HTTP開始工作前,客戶端首先會通過TCP/IP協議來和服務端建立連結(TCP三次握手)
- 建立連線後,客戶機傳送一個請求給伺服器,請求方式的格式為:統一資源識別符號(URL)、協議版本號,後邊是MIME資訊包括請求修飾符、客戶機資訊和可內容。
- 伺服器接到請求後,給予相應的響應資訊,其格式為一個狀態行,包括資訊的協議版本號、一個成功或錯誤的程式碼,後邊是MIME資訊包括伺服器資訊、實體資訊和可能的內容。
- 一般情況下,一旦Web伺服器向瀏覽器傳送了請求資料,它就要關閉TCP連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼:Connection:keep-alive,TCP連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。
- 短連線:建立連線——資料傳輸——關閉連線...建立連線——資料傳輸——關閉連線,如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費較多時間和頻寬。
- 長連線:建立連線——資料傳輸...(保持連線)...資料傳輸——關閉連線
- with pipeling: 每次建立連結後無需等待請求回來就可以傳送下一個請求
- without pipeling: 客戶端只在收到前一個請求的響應後,才發出新的請求。
- Http請求報文
客戶端傳送一個HTTP請求到伺服器的請求訊息包括以下格式: 請求行(request line)、請求頭部(header)、請求體組成 請求行: 方法: GET 獲取資源 POST 向伺服器端傳送資料,傳輸實體主體 PUT 傳輸檔案 HEAD 獲取報文首部 DELETE 刪除檔案 OPTIONS 詢問支援的方法 TRACE 追蹤路徑 URL 協議/版本號 請求頭: 通用首部(General Header) 請求首部(Request Header) 響應首部(Response Header) 實體首部(Entity Header Fields) 請求體 複製程式碼
- Http響應報文
HTTP響應組成:響應行、響應頭、響應體。 響應行 (HTTP/1.1)表明HTTP版本為1.1版本,狀態碼為200,狀態訊息為(ok) 響應頭 Date:生成響應的日期和時間; Content-Type:指定了MIME型別的HTML(text/html),編碼型別是ISO-8859-1 響應體 複製程式碼
- GET和POST區別
- GET提交的資料會放在URL之後,以?分割URL和傳輸資料,引數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的資料放在HTTP包的Body中.
- GET提交的資料大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的資料沒有限制.
- GET方式需要使用Request.QueryString來取得變數的值,而POST方式通過Request.Form來獲取變數的值。
- GET方式提交資料,會帶來安全問題,比如一個登入頁面,通過GET方式提交資料時,使用者名稱和密碼將出現在URL上,如果頁面可以被快取或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該使用者的賬號和密碼.
websocket
首先Websocket是基於HTTP協議的,或者說借用了HTTP的協議來完成一部分握手。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
複製程式碼
-
http long poll 和 ajax 輪詢都可以實現實時資訊傳遞
- ajax輪詢: 讓瀏覽器隔個幾秒就傳送一次請求,詢問伺服器是否有新資訊。
- long poll 都是採用輪詢的方式,不過採取的是阻塞模型,客戶端發起連線後,如果沒訊息,就一直不返回Response給客戶端。直到有訊息才返回,返回完之後,客戶端再次建立連線,周而復始
-
特點:
- 解決了http協議只能從客戶端向伺服器傳送請求的缺陷,有了websocket,伺服器也能主動向客戶端推送訊息
- 和http一樣,是建立在tcp協議之上,預設埠也是80和443,
- 沒有同源限制,客戶端可以與任意伺服器通訊
- 協議識別符號是ws,伺服器網址就是URL
- 可以傳送文字,也可以傳送二進位制資料
socket.io
socket.io 是一個能實現多人遠端實時通訊(聊天)的庫 它包裝的是 H5, WebSocket和輪詢, 如果是較新的瀏覽器內部使用 WebSocket,如果瀏覽器不支援, 那內部就會使用輪詢實現實時通訊
網頁從輸入網址到渲染完成經歷了哪些過程
1 輸入網址 2 傳送到DNS伺服器,並獲取域名對應的web伺服器對應的ip地址 3 與web伺服器建立TCP連線 4 瀏覽器向web伺服器傳送http請求 5 web伺服器響應請求,並返回指定url的資料(或錯誤資訊,或重定向的新的url地址) 6 瀏覽器下載web伺服器返回的資料及解析html原始檔 7 生成DOM樹,解析css和js,渲染頁面,直至顯示完成
資料結構和演算法
// reduce
function reduce(ary, f, initVal) {
var start = 0
if (arguments.length == 2) {
initVal = ary[0]
start = 1
}
for (var i = start; i < ary.length; i++) {
initVal = f(initVal, ary[i], i, ary)
}
return initVal
}
// flattenDeep
function flattenDeep(ary) {
return [].concat(...ary.map(val => {
if (Array.isArray(val)) {
return flattenDeep(val)
} else {
return val
}
}))
}
複製程式碼
ES6 新特性
- 函式預設值
- 模板字串:
123${a}456
,\ - 解構賦值
- let & const
- let 無變數提升,有塊級作用域,禁止重複宣告
- const 無變數提升,有塊級作用域,禁止重複宣告,禁止重複賦值
- 新增庫函式
- Number .EPSILON / .isInteger / .isInteger
- String .includes / .repeat / .startsWith / .endsWith
- Array .fill / .findIndex / .of() /
- Object .assign
- Math
- 箭頭函式:共享父級 this 物件,共享父級 arguments,不能當做建構函式
- 類 & 繼承
- 本質為對原型鏈的二次包裝;類沒有提升;不能使用字面量定義屬性;動態繼承類的構造方法中 super 優先 this
- 模組
- 每個模組都有自己完全獨立的程式碼塊,跟作用域類似,但是更加封閉。
- 無限制匯出匯出
- 內聯匯出:嚴格模式下執行使用 export 關鍵字,後面緊跟宣告關鍵字(let、function 等)宣告一個匯出物件,宣告並同時匯出的匯出方式
- 物件匯出
- 一個模組只能有一個預設匯出
ES8 新特性
- String:新增padStart,padEnd
- Object.values 方法返回一個給定物件自己的所有可列舉屬性值的陣列
- Object.entries 方法返回一個給定物件自身可遍歷屬性 [key, value] 的陣列
- Object.getOwnPropertyDescriptors 方法返回指定物件所有自身屬性的描述物件
- 函式引數和函式呼叫中的尾逗號
- Async 函式
BOM / DOM
- DOM文件物件模型,BOM瀏覽器物件模型
- DOM 是針對 HTML 和 XML 提供的一個API,為了能以程式設計的方法操作這個 HTML 的內容。將html中的每個元素都看作是一個物件,每個物件都叫做一個節點,這些節點組成一個DOM樹。document是DOM樹的根節點
- BOM 是瀏覽器提供的附加物件,用於處理文件之外的所有內容,比如alert/confirm/prompt,BOM包含的物件有,document,screen,location,history,navigator
- DOM是所有W3C標準都必須遵守的規則,BOM是各瀏覽器廠商遵守的規則
- BOM的核心是window,它既是通過js訪問瀏覽器視窗的一個介面,又是一個Global(全域性)物件。這意味著在網頁中定義的任何物件,變數和函式,都以window作為其global物件。
- DOM通過建立樹來表示文件,描述了處理網頁內容的方法和介面,從而使開發者對文件的內容和結構具有控制力,用DOM API可以輕鬆地刪除、新增和替換節點。
- DOM 的根節點是BOM 的window 物件的子物件。
圖片懶載入
- 三個API,我們獲得了三個值:
- 可視區高度clientHeight、
- 元素相對於其父元素容器頂部的距離offsetTop、
- 瀏覽器視窗頂部與容器元素頂部的距離也就是滾動條滾動的高度scrollTop。
- 當offsetTop - scroolTop < clientHeight,則圖片進入了可視區內,則被請求。
var imgs = document.querySelectorAll('img');
//offsetTop是元素與offsetParent的距離,迴圈獲取直到頁面頂部
function getTop(e) {
var T = e.offsetTop;
while(e = e.offsetParent) {
T += e.offsetTop;
}
return T;
}
function lazyLoad(imgs) {
var H = document.documentElement.clientHeight;//獲取可視區域高度
var S = document.documentElement.scrollTop || document.body.scrollTop;
for (var i = 0; i < imgs.length; i++) {
if (H + S > getTop(imgs[i])) {
imgs[i].src = imgs[i].getAttribute('data-src');
}
}
}
window.onload = window.onscroll = function () { //onscroll()在滾動條滾動的時候觸發
lazyLoad(imgs);
}
複製程式碼
原型,閉包,高階函式,非同步
- 閉包就是一個函式裡面生成並返回一個函式,返回的這個函式能讀取到外部函式裡面的變數
- 原型就是 a 是例項,b 是建構函式,然後a.proto === b.prototype,使用instanceof來判斷的時候就是不停地向上尋找,還有讀取a的某個屬性如果沒有,就會預設去a的原型上找
- 高階函式:高階函式是一個接收函式作為引數或將函式作為輸出返回的函式 map/reduce/filter
- 非同步:js是單執行緒的,但瀏覽器是多執行緒的,當js執行遇到非同步程式碼時,會將程式碼交給webapi非同步執行,js則可以繼續執行下面的程式碼;非同步程式碼會被塞入task queue裡排隊,task queue會一直觀察棧裡程式碼有沒有執行完成,一旦發現棧空了,就會呼叫回撥函式,然後重新回到js執行緒中執行
- www.zhihu.com/search?type…
- async表示該函式要做非同步處理。await表示後面的程式碼是一個非同步操作,等待該非同步操作完成後再執行後面的動作。如果非同步操作有返回的資料,則在左邊用一個變數來接收它。
sessionstorage localstorage cookie區別
- 傳遞方式不同 cookie資料始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和伺服器間來回傳遞。 sessionStorage和loaclStorage不會自動把資料發給伺服器,僅在本地儲存。
- 資料大小不同 cookie資料還有路徑(path)的概念,可以限制cookie只屬於某個路徑下。 cookie資料最大4k,sessionStorage和localStorage比cookie大得多,可以達到5M或者更大。
- 資料有效期不同 sessionStorage:僅在當前瀏覽器視窗關閉前有效,自然也就不可能持久保持; localStorage:始終有效,視窗或瀏覽器關閉也一直儲存,因此用作持久資料; cookie只在設定cookie過期時間之前一直有效,即使視窗或瀏覽器關閉。
- 作用域不同 sessionStorage不同的瀏覽器視窗不能共享,即使是同一個頁面; localStorage所有同源視窗都是共享的; cookie所有同源視窗中都是共享的。
session / cookie
-
Cookie 可以保持登入資訊到使用者下次與伺服器的會話,換句話說,下次訪問同一網站時,使用者會發現不必輸入使用者名稱和密碼就已經登入了(當然,不排除使用者手工刪除Cookie),Cookie滿足同源策略 Cookie 在生成時就會被指定一個Expire值,這就是Cookie的生存週期,在這個週期內Cookie有效,超出週期Cookie就會被清除。有些頁面將Cookie的生存週期設定為“0”或負值,這樣在關閉瀏覽器時,就馬上清除Cookie,不會記錄使用者資訊,更加安全。
-
由於HTTP協議是無狀態的協議,所以服務端需要記錄使用者的狀態時,就需要用某種機制來識具體的使用者,這個機制就是Session.典型的場景比如購物車,當你點選下單按鈕時,由於HTTP協議無狀態,所以並不知道是哪個使用者操作的,所以服務端要為特定的使用者建立了特定的Session,用用於標識這個使用者,並且跟蹤使用者,這樣才知道購物車裡面有幾本書。這個Session是儲存在服務端的,有一個唯一標識。
-
Session是在服務端儲存的一個資料結構,用來跟蹤使用者的狀態,這個資料可以儲存在叢集、資料庫、檔案中; Cookie是客戶端儲存使用者資訊的一種機制,用來記錄使用者的一些資訊,也是實現Session的一種方式。
event loop
第一步確認巨集任務,微任務
巨集任務:script,setTimeout,setImmediate,promise中的executor
微任務:promise.then,process.nextTick
process.nextTick優先順序高於Promise.then
timers: setTimeout / setInterval
I/O callbacks: 不在其他階段的所有回撥函式
poll: 獲取新的I/O事件
check:執行setImmediate
close callback: 執行關閉事件的回撥函式
在整個輪詢的開始執行process.nextTick
然後再執行setTimeOut、setInterval
再執行其他的回撥函式
最後執行setImmediate
複製程式碼
傳送ajax請求
axios / fetch
複製程式碼
Node.js
Node核心思想:1.非阻塞;  2.單執行緒;  3.事件驅動。
Node 是一個伺服器端 JavaScript 直譯器
當執行緒遇到IO操作的時候,不會以阻塞的方式等待IO操作完成或者資料的返回,而是將IO操作傳送給作業系統,
然後接著執行下一個操作,當作業系統執行完IO操作之後,以事件的方式通知執行IO的執行緒,
執行緒會在特定的時候執行這個事件。這一切的前提條件就是,系統需要一個事件迴圈,
以不斷的去查詢有沒有未處理的事件,然後給預處理。
複製程式碼
Redux
redux 是一個獨立的專門用於狀態管理的js庫
可以管理react應用中多個元件共享的狀態
用redux對元件的狀態進行集中式管理
元件:兩個方面
展現資料 狀態顯示
與使用者互動更新資料 更新狀態
redux核心是一個store(倉庫)
元件直接從store中讀取狀態
更新狀態:
1. Action Creators ==>> dispatch(action) :傳兩個值(type和data) type是傳的型別(刪除,增加,建立,更新)
2. store
3. Reducers ==>> 接受(previousState, action) 返回(newState)
4. React Component
createStore()
store: 管理state, reducer
方法: getState() , dispatch(action) , subscribe(listener)
action物件
reducer返回的是新的狀態
applyMiddleware 中介軟體
thunk 非同步
複製程式碼
diff演算法
- 只在同層進行比較
- 如果節點發生變化,那麼就直接替換
- 如果節點相同,遞迴比較子節點的變化
- 如果有key,那麼就會key相同的進行比較
react-redux 的核心就是一個connect函式,接收兩個引數,mapStatetoprops,mapdispatchtoprops,返回一個高階元件,這個高階元件接受一個元件,返回一個元件,但是這個返回的元件的props上面多了資料以及運算元據的方法
function connect(mapStateToProps,mapDispatchToProps){
return function(com){
return class extends React.Component{
render(){
return (
<Consumer>
{store=>{
state = mapStateToProps(store.getState())
dispatch = mapDispatchToProps(store.dispatch)
return <Comp {...state}{...dispatch}></Comp>
}}
</Consumer>
) }
}
}
}
複製程式碼
容器元件和展示元件
- 容器元件負責管理資料和邏輯
- 展示元件負責UI的呈現
- 他們通過react-redux提供的connect方法取得聯絡
為什麼連線的時候是三次握手,關閉的時候卻是四次握手?
因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。 其中ACK報文是用來應答的,SYN報文是用來同步的。 但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET, 所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。 只有等到我Server端所有的報文都傳送完了,我才能傳送FIN報文,因此不能一起傳送。故需要四步握手。
- 三次揮手:
- 客戶端傳送 SYN 包到服務端,等待服務端確認
- 服務端收到 SYN 包,同時自己也傳送一個 SYN+ACK 包給客戶端
- 客戶端接收到 SYN+ACK 包,向服務端傳送確認包 ACK ,傳送完畢,客戶端與服務端 TCP 連線成功,完成三次握手
- 四次揮手:
- 客戶端連續傳送釋放報文 FIN ,等待服務端確認
- 服務端收到釋放報文 FIN ,發出確認報文 ACK
redux
action: 是store唯一的資訊來源,把action傳送給store必須通過store的dispatch方法。
每個action必須有一個type屬性描述action的型別。
複製程式碼
XSS 與 CSRF 兩種跨站攻擊
- xss 跨站指令碼攻擊,主要是前端層面的,使用者在輸入層面插入攻擊指令碼,改變頁面的顯示,或則竊取網站 cookie,預防方法:不相信使用者的所有操作,對使用者輸入進行一個轉義,不允許 js 對 cookie 的讀寫
- csrf 跨站請求偽造,以你的名義,傳送惡意請求,通過 cookie 加引數等形式過濾
- 我們沒法徹底杜絕攻擊,只能提高攻擊門檻
負載均衡
當系統面臨大量使用者訪問,負載過高的時候,通常會使用增加伺服器數量來進行橫向擴充套件,使用叢集和負載均衡提高整個系統的處理能力
JS實現繼承的方法
1. 原型鏈繼承
將父類的例項作為子類的原型
function Cat() {}
Cat.prototype = new Animal()
Cat.prototype.name = 'cat'
var cat = new Cat()
2. 構造繼承
使用父類的建構函式來增強子類的例項,等於是複製父類的例項屬性給子類
function Cat(name) {
Animal.call(this)
instance.name = name || 'Tom'
}
var cat = new Cat()
3. 例項繼承
為父類例項新增新特性,作為子類的例項返回
function Cat(name) {
var instance = new Animal()
instance.name = name || 'Tom'
return instance
}
var cat = new Cat()
複製程式碼