display:flex; 在父元素設置,子元素受彈性盒影響,默認排成一行,若是超出一行,按比例壓縮 flex:1; 子元素設置,設置子元素如何分配父元素的空間,flex:1,子元素寬度佔滿整個父元素align-items:center 定義子元素在父容器中的對齊方式,center 垂直居中justify-content:center 設置子元素在父元素中居中,前提是子元素沒有把父元素佔滿,讓子元素水平居中。javascript
transtion transition-property 規定設置過渡效果的 CSS 屬性的名稱。css
transition-duration 規定完成過渡效果須要多少秒或毫秒。html
transition-timing-function 規定速度效果的速度曲線。前端
transition-delay 定義過渡效果什麼時候開始。vue
animation屬性能夠像Flash製做動畫同樣,經過控制關鍵幀來控制動畫的每一步,實現更爲複雜的動畫效果。java
ainimation實現動畫效果主要由兩部分組成:node
經過相似Flash動畫中的幀來聲明一個動畫;react
在animation屬性中調用關鍵幀聲明的動畫。webpack
translate 3D建模效果ios
圖片中的 alt屬性是在圖片不能正常顯示時出現的文本提示。alt有利於SEO優化
圖片中的 title屬性是在鼠標在移動到元素上的文本提示。
<style>
div {
width: 0;
height: 0;
border-top: 40px solid transparent;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
border-bottom: 40px solid #ff0000; } </style> </head> <body> <div></div> </body> 複製代碼
標準盒子模型:寬度=內容的寬度(content)+ border + padding
低版本IE盒子模型:寬度=內容寬度(content+border+padding)
已知寬度,block元素 ,添加添加margin:0 auto屬性。
已知寬度,絕對定位的居中 ,上下左右都爲0,margin:auto
div {
position: relative / fixed; /* 相對定位或絕對定位都可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
margin-top:-150px;
margin-left:-250px;
外邊距爲自身寬高的一半 */
background-color: pink; /* 方便看效果 */
}
.container {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.container div {
width: 100px; /* 可省 */
height: 100px; /* 可省 */
background-color: pink; /* 方便看效果 */
}
複製代碼
clear清除浮動(添加空div法)在浮動元素下方添加空div,並給該元素寫css樣式 {clear:both;height:0;overflow:hidden;}
給浮動元素父級設置高度
父級同時浮動(須要給父級同級元素添加浮動)
父級設置成inline-block,其margin: 0 auto居中方式失效
給父級添加overflow:hidden 清除浮動方法
萬能清除法 after僞類 清浮動(如今主流方法,推薦使用)
float_div:after{
content:"."; clear:both; display:block; height:0; overflow:hidden; visibility:hidden; } .float_div{ zoom:1 } 複製代碼
聖盃佈局/雙飛翼佈局
<style>
* {
margin: 0;
padding: 0;
}
.middle,
.left,
.right {
position: relative;
float: left; min-height: 130px; } .container { padding: 0 220px 0 200px; overflow: hidden; } .left { margin-left: -100%; left: -200px; width: 200px; background: red; } .right { margin-left: -220px; right: -220px; width: 220px; background: green; } .middle { width: 100%; background: blue; word-break: break-all; } </style> </head> <body> <div class='container'> <div class='middle'></div> <div class='left'></div> <div class='right'></div> </div> </body> 複製代碼
display:none 隱藏對應的元素,在文檔佈局中再也不給它分配空間,它各邊的元素會合攏,就當他歷來不存在。
visibility:hidden 隱藏對應的元素,可是在文檔佈局中仍保留原來的空間。
link屬於HTML標籤,而@import是CSS提供的頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載
import只在IE5以上才能識別,而link是HTML標籤,無兼容問題
link方式的樣式的權重 高於@import的權重.
共同點: 改變行內元素的呈現方式,display被置爲block 讓元素脫離普通流,不佔據空間 默認會覆蓋到非定位元素上
不一樣點: absolute的」根元素「是能夠設置的 fixed的」根元素「固定爲瀏覽器窗口。當你滾動網頁,fixed元素與瀏覽器窗口之間的距離是不變的。
Animation和transition大部分屬性是相同的,他們都是隨時間改變元素的屬性值,他們的主要區別是transition須要觸發一個事件才能改變屬性, 而animation不須要觸發任何事件的狀況下才會隨時間改變屬性值,而且transition爲2幀,從from .... to,而animation能夠一幀一幀的。
transition 規定動畫的名字 規定完成過渡效果須要多少秒或毫秒 規定速度效果 定義過渡效果什麼時候開始 animation 指定要綁定到選擇器的關鍵幀的名稱
不一樣級別:總結排序:!important > 行內樣式>ID選擇器 > 類選擇器 > 標籤 > 通配符 > 繼承 > 瀏覽器默認屬性
1.屬性後面加!import 會覆蓋頁面內任何位置定義的元素樣式
2.做爲style屬性寫在元素內的樣式
3.id選擇器
4.類選擇器
5.標籤選擇器
6.通配符選擇器(*)
7.瀏覽器自定義或繼承
**同一級別:後寫的會覆蓋先寫的**
複製代碼
css選擇器的解析原則:選擇器定位DOM元素是從右往左的方向,這樣能夠儘早的過濾掉一些沒必要要的樣式規則和元素
多個圖片集成在一個圖片中的圖
使用雪碧圖能夠減小網絡請求的次數,加快容許的速度
經過background-position,去定位圖片在屏幕的哪一個位置
複製代碼
相同點: 都經常使用來判斷一個變量是否爲空,或者是什麼類型的。
不一樣點: typeof 返回值是一個字符串,用來講明變量的數據類型 instanceof 用於判斷一個變量是否屬於某個對象的實例.
visibility:hidden、display:none、z-index=-一、opacity:0
1.opacity:0,該元素隱藏起來了,但不會改變頁面佈局,而且,若是該元素已經綁定了一些事件,如click事件也能觸發
2.visibility:hidden,該元素隱藏起來了,但不會改變頁面佈局,可是不會觸發該元素已經綁定的事件
3.display:node, 把元素隱藏起來,而且會改變頁面佈局,能夠理解成在頁面中把該元素刪掉
複製代碼
淺克隆: 只是拷貝了基本類型的數據,而引用類型數據,複製後也是會發生引用,咱們把這種拷貝叫作「(淺複製)淺拷貝」,換句話說,淺複製僅僅是指向被複制的內存地址,若是原地址中對象被改變了,那麼淺複製出來的對象也會相應改變。
深克隆: 建立一個新對象,屬性中引用的其餘對象也會被克隆,再也不指向原有對象地址。 JSON.parse、JSON.stringify()
let定義塊級做用域變量 沒有變量的提高,必須先聲明後使用 let聲明的變量,不能與前面的let,var,conset聲明的變量重名
const 定義只讀變量 const聲明變量的同時必須賦值,const聲明的變量必須初始化,一旦初始化完畢就不容許修改 const聲明變量也是一個塊級做用域變量 const聲明的變量沒有「變量的提高」,必須先聲明後使用 const聲明的變量不能與前面的let, var , const聲明的變量重 const定義的對象\數組中的屬性值能夠修改,基礎數據類型不能夠
ES6能夠給形參函數設置默認值
在數組以前加上三個點(...)展開運算符
數組的解構賦值、對象的解構賦值
箭頭函數的特色 箭頭函數至關於匿名函數,是不能做爲構造函數的,不能被new 箭頭函數沒有arguments實參集合,取而代之用...剩餘運算符解決 箭頭函數沒有本身的this。他的this是繼承當前上下文中的this 箭頭函數沒有函數原型 箭頭函數不能當作Generator函數,不能使用yield關鍵字 不能使用call、apply、bind改變箭頭函數中this指向 Set數據結構,數組去重
=賦值
==返回一個布爾值;相等返回true,不相等返回false; 容許不一樣數據類型之間的比較; 若是是不一樣類型的數據進行,會默認進行數據類型之間的轉換; 若是是對象數據類型的比較,比較的是空間地址
=== 只要數據類型不同,就返回false;
一、js工廠模式
二、js構造函數模式
三、js原型模式
四、構造函數+原型的js混合模式
五、構造函數+原型的動態原型模式
六、觀察者模式
七、發佈訂閱模式
複製代碼
call() 和apply()的第一個參數相同,就是指定的對象。這個對象就是該函數的執行上下文。
call()和apply()的區別就在於,二者之間的參數。
call()在第一個參數以後的 後續全部參數就是傳入該函數的值。
apply() 只有兩個參數,第一個是對象,第二個是數組,這個數組就是該函數的參數。 bind() 方法和前二者不一樣在於: bind() 方法會返回執行上下文被改變的函數而不會當即執行,而前二者是 直接執行該函數。他的參數和call()相同。
原型鏈繼承 核心: 將父類的實例做爲子類的原型
構造繼承 核心:使用父類的構造函數來加強子類實例,等因而複製父類的實例屬性給子類
實例繼承 核心:爲父類實例添加新特性,做爲子類實例返回
拷貝繼承
組合繼承 核心:經過調用父類構造,繼承父類的屬性並保留傳參的優勢,而後經過將父類實例做爲子類原型,實現 函數複用
寄生組合繼承 核心:經過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實 例方法/屬性,避免的組合繼承的缺點
我的感受,簡單來講閉包就是在函數裏面聲明函數,本質上說就是在函數內部和函數外部搭建起一座橋樑,使得子函數能夠訪問父函數中全部的局部變量,可是反之不能夠,這只是閉包的做用之一,另外一個做用,則是保護變量不受外界污染,使其一直存在內存中,在工做中咱們仍是少使用閉包的好,由於閉包太消耗內存,不到萬不得已的時候儘可能不使用。
把全部的對象共用的屬性所有放在堆內存的一個對象(共用屬性組成的對象),而後讓每個對象的 __proto__存儲這個「共用屬性組成的對象」的地址。而這個共用屬性就是原型,原型出現的目的就是爲了減小沒必要要的內存消耗。而原型鏈就是對象經過__proto__向當前實例所屬類的原型上查找屬性或方法的機制,若是找到Object的原型上仍是沒有找到想要的屬性或者是方法則查找結束,最終會返回undefined
將html代碼按照深度優先遍從來生成DOM樹。 css文件下載完後也會進行渲染,生成相應的CSSOM。 當全部的css文件下載完且全部的CSSOM構建結束後,就會和DOM一塊兒生成Render Tree。 接下來,瀏覽器就會進入Layout環節,將全部的節點位置計算出來。 最後,經過Painting環節將全部的節點內容呈現到屏幕上。
一、瀏覽器的地址欄輸入URL並按下回車。
二、瀏覽器查找當前URL是否存在緩存,並比較緩存是否過時。三、DNS解析URL對應的IP。
四、根據IP創建TCP鏈接(三次握手)。
五、HTTP發起請求。
六、服務器處理請求,瀏覽器接收HTTP響應。
七、渲染頁面,構建DOM樹。
八、關閉TCP鏈接(四次揮手)
複製代碼
相同點 都是保存在瀏覽器端,且同源的。
不一樣點
同源策略(協議+端口號+域名要相同)
一、jsonp跨域(只能解決get) 原理:動態建立一個script標籤。利用script標籤的src屬性不受同源策略限制,由於全部的src屬性和href屬性都不受同源策略的限制,能夠請求第三方服務器資源內容
步驟: 1).去建立一個script標籤 2).script的src屬性設置接口地址 3).接口參數,必需要帶一個自定義函數名,要否則後臺沒法返回數據 4).經過定義函數名去接受返回的數據
二、document.domain 基礎域名相同 子域名不一樣
三、window.name 利用在一個瀏覽器窗口內,載入全部的域名都是共享一個window.name
四、服務器設置對CORS的支持 原理:服務器設置Access-Control-Allow-Origin HTTP響應頭以後,瀏覽器將會容許跨域請求
五、利用h5新特性window.postMessage()
1.建立ajax實例
2.執行open 肯定要訪問的連接 以及同步異步
3.監聽請求狀態
4.發送請求
ES6的set對象 先將原數組排序,在與相鄰的進行比較,若是不一樣則存入新數組
function unique(arr){ var arr2 = arr.sort(); var res = [arr2[0]]; for(var i=1;i<arr2.length;i++){ if(arr2[i] !== res[res.length-1]){ res.push(arr2[i]); } } return res; } 利用下標查詢 function unique(arr){ var newArr = [arr[0]]; for(var i=1;i<arr.length;i++){ if(newArr.indexOf(arr[i]) == -1){ newArr.push(arr[i]); } } return newArr; } 複製代碼
2開頭
3開頭
以4開頭的都是客戶端的問題;
以5開頭都是服務端的問題
同步:在同一時間內作一件事情
異步:在同一時間內作多個事情 JS是單線程的,每次只能作一件事情,JS運行在瀏覽器中,瀏覽器是多線程的,能夠在同一時間執行多個任務。
定時器、ajax、事件綁定、回調函數、async await、promise
三次握手
四次揮手
創建鏈接的時候, 服務器在LISTEN狀態下,收到創建鏈接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。 而關閉鏈接時,服務器收到對方的FIN報文時,僅僅表示對方再也不發送數據了可是還能接收數據,而本身也未必所有數據都發送給對方了,因此己方能夠當即關閉,也能夠發送一些數據給對方後,再發送FIN報文給對方來表示贊成如今關閉鏈接,所以,己方ACK和FIN通常都會分開發送,從而致使多了一次。
- 若是元素類型發生變化,直接替換
- 若是是文本,則比較文本里面的內容,是否有差別,若是是元素就須要比較當前元素的屬性是否相等,會先比較key, 在比較類型 爲何 react中循環 建議不要使用索引 ,若是純爲了展現 那能夠使用索引
全局做用域
私有做用域
塊級做用域
上級做用域
他是ES6中新增長的一個類(new Promise),目的是爲了管理JS中的異步編程的,因此把他稱爲「Promise設計模式」 new Promise 經歷三個狀態:padding(準備狀態:初始化成功、開始執行異步的任務)、fullfilled(成功狀態)、rejected(失敗狀態)== Promise自己是同步編程的,他能夠管理異步操做的(重點),new Promise的時候,會把傳遞的函數當即執行 Promise函數天生有兩個參數,resolve(當異步操做執行成功,執行resolve方法),rejected(當異步操做失敗,執行reject方法) then()方法中有兩個函數,第一個傳遞的函數是resolve,第二個傳遞的函數是reject ajax中false表明同步,true表明異步,若是使用異步,不等ajax完全完成
相同點
不一樣點
注意:forEach對於空數組是不會調用回調函數的。
async/await函數是異步代碼的新方式
async/await是基於promise實現的
async/await使異步代碼更像同步代碼
await 只能在async函數中使用,不能再普通函數中使用,要成對出現
默認返回一個promise實例,不能被改變
await下面的代碼是異步,後面的代碼是同步的
- 全局做用域下的this指向window
- 若是給元素的事件行爲綁定函數,那麼函數中的this指向當前被綁定的那個元素
- 函數中的this,要看函數執行前有沒有 . , 有 . 的話,點前面是誰,this就指向誰,若是沒有點,指向window
- 自執行函數中的this永遠指向window
- 定時器中函數的this指向window
- 構造函數中的this指向當前的實例
- call、apply、bind能夠改變函數的this指向
- 箭頭函數中沒有this,若是輸出this,就會輸出箭頭函數定義時所在的做用域中的this
全部的函數數據類型都天生自帶一個prototype屬性,該屬性的屬性值是一個對象 prototype的屬性值中天生自帶一個constructor屬性,其constructor屬性值指向當前原型所屬的類 全部的對象數據類型,都天生自帶一個_proto_屬性,該屬性的屬性值指向當前實例所屬類的原型
promise、generator、async/await
promise: 1.是一個對象,用來傳遞異步操做的信息。表明着某個將來纔會知道結果的時間,並未這個事件提供統一的api,供進異步處理
2.有了這個對象,就可讓異步操做以同步的操做的流程來表達出來,避免層層嵌套的回調地獄
3.promise表明一個異步狀態,有三個狀態pending(進行中),Resolve(以完成),Reject(失敗)
4.一旦狀態改變,就不會在變。任什麼時候候均可以獲得結果。從進行中變爲以完成或者失敗
promise.all() 裏面狀態都改變,那就會輸出,獲得一個數組
promise.race() 裏面只有一個狀態變爲rejected或者fulfilled即輸出
promis.finally()無論指定無論Promise對象最後狀態如何,都會執行的操做(本質上仍是then方法的特例)
複製代碼
事件流描述的是從頁面中接受事件的順序,事件 捕獲階段 處於目標階段 事件冒泡階段 addeventListener 最後這個布爾值參數若是是true,表示在捕獲階段調用事件處理程序;若是是false,表示在冒泡階段調用事件處理程序。
一、事件捕獲階段:實際目標div在捕獲階段不會接受事件,也就是在捕獲階段,事件從document到<html>再到<body>就中止了。
二、處於目標階段:事件在div發生並處理,可是事件處理會被當作是冒泡階段的一部分。
三、冒泡階段:事件又傳播迴文檔
阻止冒泡事件event.stopPropagation()
function stopBubble(e) {
if (e && e.stopPropagation) { // 若是提供了事件對象event 這說明不是IE瀏覽器
e.stopPropagation()
} else {
window.event.cancelBubble = true //IE方式阻止冒泡
}
}
阻止默認行爲event.preventDefault()
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault()
} else {
// IE瀏覽器阻止函數器默認動做的行爲
window.event.returnValue = false
}
}
複製代碼
在DOM標準事件模型中,是先捕獲後冒泡。可是若是要實現先冒泡後捕獲的效果, 對於同一個事件,監聽捕獲和冒泡,分別對應相應的處理函數,監聽到捕獲事件,先暫緩執行,直到冒泡事件被捕獲後再執行捕獲事件。
千萬不要使用typeof來判斷對象和數組,由於這種類型都會返回object。
複製代碼
typeOf()是判斷基本類型的Boolean,Number,symbol, undefined, String。 對於引用類型:除function,都返回object null返回object。
installOf() 用來判斷A是不是B的實例,installof檢查的是原型。
toString() 是Object的原型方法,對於 Object 對象,直接調用 toString() 就能返回 [Object Object] 。而對於其餘對象,則須要經過 call / apply 來調用才能返回正確的類型信息。
hasOwnProperty()方法返回一個布爾值,指示對象自身屬性中是否具備指定的屬性,該方法會忽略掉那些從原型鏈上繼承到的屬性。
isProperty()方法測試一個對象是否存在另外一個對象的原型鏈上。
由於js是單線程的。瀏覽器遇到etTimeout 和 setInterval會先執行完當前的代碼塊,在此以前會把定時器推入瀏覽器的
待執行時間隊列裏面,等到瀏覽器執行完當前代碼以後會看下事件隊列裏有沒有任務,有的話才執行定時器裏的代碼
複製代碼
1.slice(start,end):方法能夠從已有數組中返回選定的元素,返回一個新數組,
包含從start到end(不包含該元素)的數組方法
注意:該方法不會更新原數組,而是返回一個子數組
2.splice():該方法想或者從數組中添加或刪除項目,返回被刪除的項目。(該方法會改變原數組)
splice(index, howmany,item1,...itemx)
·index參數:必須,整數規定添加或刪除的位置,使用負數,從數組尾部規定位置
·howmany參數:必須,要刪除的數量,
·item1..itemx:可選,向數組添加新項目
3.map():會返回一個全新的數組。使用於改變數據值的時候。會分配內存存儲空間數組並返回,forEach()不會返回數據
4.forEach(): 不會返回任何有價值的東西,而且不打算改變數據,單純的只是想用數據作一些事情,他容許callback更改原始數組的元素
5.reduce(): 方法接收一個函數做爲累加器,數組中的每個值(從左到右)開始縮減,最終計算一個值,不會改變原數組的值
6.filter(): 方法建立一個新數組,新數組中的元素是經過檢查指定數組中符合條件的全部元素。它裏面經過function去作處理
複製代碼
vue是一個漸進式的JS框架。他易用,靈活,高效; 能夠把一個頁面分隔成多個組件;當其餘頁面有相似功能時,直接讓封裝的組件進行復用; 他是構建用戶界面的聲明式框架,只關心圖層;不關心具體是如何實現的
Vue的雙向數據綁定是由數據劫持結合發佈者訂閱者實現的。 數據劫持是經過Object.defineProperty()來劫持對象數據的setter和getter操做。 在數據變更時做你想作的事
- 原理 經過Observer來監聽本身的model數據變化,經過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通訊橋樑,達到數據變化->視圖更新 在初始化vue實例時,遍歷data這個對象,給每個鍵值對利用Object.definedProperty對data的鍵值對新增get和set方法,利用了事件監聽DOM的機制,讓視圖去改變數據
react總體是函數式的思想,把組件設計成純組件,狀態和邏輯經過參數傳入,因此在react中,是單向數據流;
vue的思想是響應式的,也就是基因而數據可變的,經過對每個屬性創建Watcher來監聽,當屬性變化的時候,響應式的更新對應的虛擬dom。
頁面經過mapAction異步提交事件到action。action經過commit把對應參數同步提交到mutation。
mutation會修改state中對於的值。 最後經過getter把對應值跑出去,在頁面的計算屬性中
經過mapGetter來動態獲取state中的值
複製代碼
- state中保存着共有數據,數據是響應式的
- getter能夠對state進行計算操做,主要用來過濾一些數據,能夠在多組件之間複用
- mutations定義的方法動態修改state中的數據,經過commit提交方法,方法必須是同步的
- actions將mutations裏面處理數據的方法變成異步的,就是異步操做數據,通store.dispatch來分發actions,把異步的方法寫在actions中,經過commit提交mutations,進行修改數據。
- modules:模塊化vuex
- hash ——即地址欄URL中的#符號(此hsah 不是密碼學裏的散列運算) hash 雖然出現URL中,但不會被包含在HTTP請求中,對後端徹底沒有影響,所以改變hash不會從新加載頁面。
- history ——利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法
這兩個方法應用於瀏覽器的歷史記錄站,在當前已有的back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改是,雖然改變了當前的URL,但你瀏覽器不會當即向後端發送請求。
當 Vue.js 用v-for正在更新已渲染過的元素列表時,它默認用「就地複用」策略。 若是數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。
key的做用主要是爲了高效的更新虛擬DOM。
$route
和$router
的區別
- $route是「路由信息對象」,包括path,params,hash,query,fullPath,matched,name等路由信息參數。
- $router是「路由實例」對象包括了路由的跳轉方法,鉤子函數等。
- 導航守衛 router.beforeEach 全局前置守衛
// main.js 入口文件
import router from './router'; // 引入路由 router.beforeEach((to, from, next) => { next(); }); router.beforeResolve((to, from, next) => { next(); }); router.afterEach((to, from) => { console.log('afterEach 全局後置鉤子'); }); 複製代碼
路由獨享的守衛 你能夠在路由配置上直接定義 beforeEnter 守衛
const router = new VueRouter({
routes: [
{
path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] }) 複製代碼
組件內的守衛 你能夠在路由組件內直接定義如下路由導航守衛
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 由於當守衛執行前,組件實例還沒被建立
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,可是該組件被複用時調用
// 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。
// 能夠訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用,咱們用它來禁止用戶離開
// 能夠訪問組件實例 `this`
// 好比還未保存草稿,或者在用戶離開前,
將setInterval銷燬,防止離開以後,定時器還在調用。 } } 複製代碼
請求後臺資源的模塊。
$ npm install axios -S裝好
複製代碼
而後發送的是跨域,需在配置文件中config/index.js進行設置。後臺若是是Tp5則定義一個資源路由。 js中使用import進來,而後.get或.post。返回在.then函數中若是成功,失敗則是在.catch函數中
1.不要在模板裏面寫過多表達式
2.循環調用子組件時添加key
3.頻繁切換的使用v-show,不頻繁切換的使用v-if
4.儘可能少用float,能夠用flex
5.按需加載,能夠用require或者import()按需加載須要的組件
6.路由懶加載
- extend 是構造一個組件的語法器。 而後這個組件你能夠做用到Vue.component這個全局註冊方法裏 還能夠在任意vue模板裏使用組件。 也能夠做用到vue實例或者某個組件中的components屬性中並在內部使用apple組件。
- Vue.component 你能夠建立 ,也能夠取組件。
png24位的圖片在iE6瀏覽器上出現背景 解決方案是作成PNG8.也能夠引用一段腳本處理.
瀏覽器默認的margin和padding不一樣。 解決方案是加一個全局的*{margin:0;padding:0;}來統一。
IE6雙邊距bug:塊屬性標籤float後,又有橫行的margin狀況下,在ie6顯示margin比設置的大。
浮動ie產生的雙倍距離(IE6雙邊距問題:在IE6下,若是對元素設置了浮動,同時又設置了margin-left或margin-right,margin值會加倍。) #box{ float:left; width:10px; margin:0 0 0 100px;}
=> 相同點:
1.數據驅動頁面,提供響應式的試圖組件
2.都有virtual DOM,組件化的開發,經過props參數進行父子之間組件傳遞數據,都實現了webComponents規範
3.數據流動單向,都支持服務器的渲染SSR
4.都有支持native的方法,react有React native, vue有wexx
=> 不一樣點:
1.數據綁定:Vue實現了雙向的數據綁定,react數據流動是單向的
2.數據渲染:大規模的數據渲染,react更快
3.使用場景:React配合Redux架構適合大規模多人協做複雜項目,Vue適合小快的項目
4.開發風格:react推薦作法jsx + inline style把html和css都寫在js了
vue是採用webpack + vue-loader單文件組件格式,html, js, css同一個文件
複製代碼
Redux數據流裏,reduces實際上是根據以前的狀態(previous state)和現有的action(current action)
更新state(這個state能夠理解爲上下累加器的結果)
每次redux reducer被執行時,state和action被傳入,這個state根據action進行累加或者是'自身消減'(reduce),
進而返回最新的state,這也就是典型reduce函數的用法:state -> action -> state
複製代碼
refs就想一個逃生窗,容許咱們之間訪問dom元素或者組件實例,能夠向組件添加一個ref屬性的值是一個回調函數,
它將接受地城dom元素或組件的已掛在實例,做爲第一個參數
複製代碼
幫組咱們跟蹤哪些項目已更改、添加、從列表中刪除,key是獨一無二的,可讓咱們高效的去定位元素,而且操做它
複製代碼
三個狀態:Mounting(已插入真實的DOM)
Updating(正在被從新渲染)
Unmounting(已移除真實的DOM)
componentDIdMount 在第一次渲染後調用,只在客服端。以後組件已經生成對應的DOM結構,
componentDidUpdate 在組件完成更新後當即調用,在出初始化是不會調用
複製代碼
父組件經過props 給子組件傳遞數據,子組件則是經過調用父組件傳給它的函數給父組件傳遞數據。
複製代碼
虛擬DOM至關於在js和真實dom中間加了一個緩存,利用dom diff算法避免了沒有必要的doom操做,從而提升性能
具體實現步驟:
·用JavaScript對象結構表示DOM樹的結構;而後用這個樹構建一個真正的DOM樹,插到文檔中
·當狀態變動的時候,從新構造一棵樹的對象樹,而後用新的樹和舊的樹進行對比,記錄兩棵樹差別
·把2所記錄的差別應用到步驟1所構建的真正的DOM樹上,試圖就更新了。
複製代碼
1.把樹形結構按照層級分解,只比較同級元素
2.給列表結構的每一個單元添加key屬性,方便比較。在實際代碼中,會對新舊兩棵樹進行一個深度優先的遍歷,這樣每一個節點都會有一個標記
3.在深度優先遍歷的時候,每遍歷到一個節點就把該節點和新的樹進行對比。若是有差別的話就記錄到一個對象裏面
Vritual DOM 算法主要實現上面步驟的三個函數:element, diff, patch。而後就能夠實際的進行使用
react只會匹配相同的class的component(這裏的class指的是組件的名字)
合併操做,條用component的setState方法的時候,React將其標記爲dirty.到每個時間循環借宿,React檢查全部標記dirty的component從新繪製
4.選擇性子樹渲染。能夠重寫shouldComponentUpdate提升diff的性能
複製代碼
flux的最大特色,就是數據的‘單向流動’
1.用戶訪問View
2.View發出用戶的Action
3.Dispatcher收到Action,要求state進行相應的更新
4.store更新後,發出一個‘change’事件後,更新頁面
複製代碼
shouldComponentUpdate 這個方法用來判斷是否須要調用render方法從新描繪dom.由於dom的描繪很是消耗性能,
若是咱們在shouldComponentUpdate方法中可以寫出更優化的dom diff算法,能夠極大的提升性能
複製代碼
根據組件的職責一般把組件分爲UI組件和容器組件
UI組件負責UI的呈現,容器組件負責管理數據和邏輯
二者經過React-redux提供connect方法聯繫起來
複製代碼
setState經過一個隊列機制實現state更新,當執行setState時,會將須要更新的state很後放入狀態隊列
而不會當即更新this.state,隊列機制能夠高效地批量更新state。若是不經過setState而直接修改this.state的值
那麼該state將不會被放入狀態隊列中。當下次調用setState並對狀態隊列進行合併時,就會忽略以前修改的state,形成不可預知的錯誤
同時,也利用了隊列機制實現了setState的異步更新,避免了頻繁的重複更新state
同步更新state:
setState 函數並不會阻塞等待狀態更新完畢,所以 setNetworkActivityIndicatorVisible 有可能先於數據渲染完畢就執行。
第二個參數是一個回調函數,在setState的異步操做結束而且組件已經從新渲染的時候執行
也就是說,咱們能夠經過這個回調來拿到更新的state的值,實現代碼的同步
例子:componentDidMount() {
fetch('https://test.com')
.then((res) => res.json())
.then(
(data) => {
this.setState({ data:data });
StatusBar.setNetworkActivityIndicatorVisible(false);
}
複製代碼
1.異步加載模塊
2.提取第三庫
3.代碼壓縮
4.去除沒必要要的插件
複製代碼
1、減小代碼體積 1.使用CommonsChunksPlugin 提取多個chunk之間的通用模塊,減小整體代碼體積
2.把部分依賴轉移到CDN上,避免每次編譯過程都由Webpack處理
3.對一些組件庫採用按需加載,避免無用的代碼
2、減小目錄檢索範圍
·在使用loader的時候,經過制定exclude和include選項,減小loader遍歷的目錄範圍,從而加快webpack編譯速度
3、減小檢索路經:resolve.alias能夠配置webpack模塊解析的別名,對於比較深的解析路經,能夠對其配置alias
複製代碼
一、首屏加載和按需加載,懶加載
二、資源預加載
三、圖片壓縮處理,使用base64內嵌圖片
四、合理緩存dom對象
五、使用touchstart代替click(click 300毫秒的延遲)
六、利用transform:translateZ(0),開啓硬件GUP加速
七、不濫用web字體,不濫用float(佈局計算消耗性能),減小font-size聲明
八、使用viewport固定屏幕渲染,加速頁面渲染內容
九、儘可能使用事件代理,避免直接事件綁定
複製代碼
1.減小入口文件體積
2.靜態資源本地緩存
3.開啓Gzip壓縮
4.使用SSR,nuxt.js
複製代碼
由來:
300毫米延遲解決的是雙擊縮放。雙擊縮放,手指在屏幕快速點擊兩次。safari瀏覽器就會將網頁縮放值原始比例。因爲用戶能夠雙擊縮放或者是滾動的操做,
當用戶點擊屏幕一次以後,瀏覽器並不會判斷用戶確實要打開至這個連接,仍是想要進行雙擊操做
所以,safair瀏覽器就會等待300ms,用來判斷用戶是否在次點擊了屏幕
解決方案:1.禁用縮放,設置meta標籤 user-scalable=no
2.fastclick.js
原理:FastClick的實現原理是在檢查到touchend事件的時候,會經過dom自定義事件當即
發出click事件,並把瀏覽器在300ms以後真正的click事件阻止掉
fastclick.js還能夠解決穿透問題
複製代碼
在不改變外部行爲的前提下,簡化結構、添加可讀性
2XX(成功處理了請求狀態)
200 服務器已經成功處理請求,並提供了請求的網頁
201 用戶新建或修改數據成功
202 一個請求已經進入後臺
204 用戶刪除成功
3XX(每次請求使用的重定向不要超過5次)
304 網頁上次請求沒有更新,節省帶寬和開銷
4XX(表示請求可能出錯,妨礙了服務器的處理)
400 服務器不理解請求的語法
401 用戶沒有權限(用戶名,密碼輸入錯誤)
403 用戶獲得受權(401相反),可是訪問被禁止
404 服務器找不到請求的網頁,
5XX(表示服務器在處理請求的時候發生內部錯誤)
500 服務器遇到錯誤,沒法完成請求
503 服務器目前沒法使用(超載或停機維護)
複製代碼
1.服務器首先產生Etag,服務器可在稍後使用它來判斷頁面是否被修改。本質上,客戶端經過該記號傳回服務器要求服務器驗證(客戶端)緩存)
2.304是 HTTP的狀態碼,服務器用來標識這個文件沒有被修改,不返回內容,瀏覽器接受到這個狀態碼會去去找瀏覽器緩存的文件
3.流程:客戶端請求一個頁面A。服務器返回頁面A,並在A上加一個Tage客服端渲染該頁面,並把Tage也存儲在緩存中。客戶端再次請求頁面A
並將上次請求的資源和ETage一塊兒傳遞給服務器。服務器檢查Tage.而且判斷出該頁面自上次客戶端請求以後未被修改。直接返回304
last-modified: 客服端請求資源,同時有一個last-modified的屬性標記此文件在服務器最後修改的時間
客服端第二次請求此url時,根據http協議。瀏覽器會向服務器發送一個If-Modified-Since報頭,
詢問該事件以後文件是否被修改,沒修改返回304
有了Last-Modified,爲何還要用ETag?
一、由於若是在一秒鐘以內對一個文件進行兩次更改,Last-Modified就會不正確(Last—Modified不能識別秒單位的修改)
二、某些服務器不能精確的獲得文件的最後修改時間
三、一些文件也行會週期新的更改,可是他的內容並不改變(僅僅改變修改的事件),這個時候咱們並不但願客戶端認爲文件被修改,而從新Get
ETag,爲何還要用Last-Modified?
一、二者互補,ETag的判斷的缺陷,好比一些圖片等靜態文件的修改
二、若是每次掃描內容都生成ETag比較,顯然要比直接比較修改時間慢的多。
ETag是被請求變量的實體值(文件的索引節,大小和最後修改的時間的Hash值)
一、ETag的值服務器端對文件的索引節,大小和最後的修改的事件進行Hash後獲得的。
複製代碼
1.get數據是存放在url以後,以?分割url和傳輸數據,參數之間以&相連; post方法是把提交的數據放在http包的Body中
2.get提交的數據大小有限制,(由於瀏覽器對url的長度有限制),post的方法提交的數據沒有限制
3.get須要request.queryString來獲取變量的值,而post方式經過request.from來獲取變量的值
4.get的方法提交數據,會帶來安全問題,好比登陸一個頁面,經過get的方式提交數據,用戶名和密碼就會出如今url上
複製代碼
1.超文本的傳輸協議,是用於從萬維網服務器超文本傳輸到本地資源的傳輸協議
2.基於TCP/IP通訊協議來傳遞數據(HTML,圖片資源)
3.基於運用層的面向對象的協議,因爲其簡潔、快速的方法、適用於分佈式超媒體信息系統
4.http請求信息request:
請求行(request line)、請求頭部(header),空行和請求數據四部分構成
請求行,用來講明請求類型,要訪問的資源以及所使用的HTTP版本.
請求頭部,用來講明服務器要使用的附加信息
空行,請求頭部後面的空行是必須的
請求數據也叫主體,能夠添加任意的其餘數據。
5.http相應信息Response
狀態行、消息報頭、空行和響應正文
狀態行,由HTTP協議版本號, 狀態碼, 狀態消息 三部分組成
消息報頭,用來講明客戶端要使用的一些附加信息
空行,消息報頭後面的空行是必須的
響應正文,服務器返回給客戶端的文本信息。
複製代碼
https:是以安全爲目標的HTTP通道,簡單講是HTTP的安全版本,經過SSL加密
http:超文本傳輸協議。是一個客服端和服務器端請求和應答的標準(tcp),使瀏覽器更加高效,使網絡傳輸減小
複製代碼
長鏈接:HTTP1.0須要使用keep-alive參數來告知服務器創建一個長鏈接,而HTP1.1默認支持長鏈接
節約寬帶:HTTP1.1支持只發送一個header信息(不帶任何body信息)
host域(設置虛擬站點,也就是說,web server上的多個虛擬站點能夠共享同一個ip端口):HTTP1.0沒有host域
1.http2採用的二進制文本傳輸數據,而非http1文本格式,二進制在協議的解析和擴展更好
2.數據壓縮:對信息頭採用了HPACK進行壓縮傳輸,節省了信息頭帶來的網絡流量
3.多路複用:一個鏈接能夠併發處理多個請求
4.服務器推送:咱們對支持HTTP2.0的web server請求數據的時候,服務器會順便把一些客戶端須要的資源一塊兒推送到客戶端,省得客戶端再次建立鏈接發送請求到服務器端獲取。這種方式很是合適加載靜態資源
複製代碼
1.web緩存就是存在於客戶端與服務器之間的一個副本、當你第一個發出請求後,緩存根據請求保存輸出內容的副本
2.緩存的好處
(1)減小沒必要要的請求
(2)下降服務器的壓力,減小服務器的消耗
(3)下降網絡延遲,加快頁面打開速度(直接讀取瀏覽器的數據)
複製代碼
1.sql注入原理:是將sql代碼假裝到輸入參數中,傳遞到服務器解析並執行的一種攻擊手法。也就是說,
在一些對server端發起的請求參數中植入一些sql代碼,server端在執行sql操做時,會拼接對應參數,
同時也將一些sql注入攻擊的「sql」拼接起來,致使會執行一些預期以外的操做。
防範:1.對用戶輸入進行校驗
2.不適用動態拼接sql
2.XSS(跨站腳本攻擊):往web頁面插入惡意的html標籤或者js代碼。
舉例子:在論壇放置一個看是安全的連接,竊取cookie中的用戶信息
防範:1.儘可能採用post而不使用get提交表單
2.避免cookie中泄漏用戶的隱式
3.CSRF(跨站請求假裝):經過假裝來自受信任用戶的請求
舉例子:黃軼老師的webapp音樂請求數據就是利用CSRF跨站請求假裝來獲取QQ音樂的數據
防範:在客服端頁面增長僞隨機數,經過驗證碼
XSS和CSRF的區別:
1.XSS是獲取信息,不須要提早知道其餘用戶頁面的代碼和數據包
2.CSRF代替用戶完成指定的動做,須要知道其餘頁面的代碼和數據包
複製代碼
1.儘量的避開互聯網有可能影響數據傳輸速度和穩定性的瓶頸和環節。使內容傳輸的更快更穩定。
2.關鍵技術:內容存儲和分發技術中
3.基本原理:普遍採用各類緩存服務器,將這些緩存服務器分佈到用戶訪問相對的地區或者網絡中。當用戶訪問網絡時利用全局負載技術
將用戶的訪問指向距離最近的緩存服務器,由緩存服務器直接相應用戶的請求(全局負載技術)
複製代碼
客服端發c起請求鏈接服務器端s確認,服務器端也發起鏈接確認客服端確認。
第一次握手:客服端發送一個請求鏈接,服務器端只能確認本身能夠接受客服端發送的報文段
第二次握手: 服務端向客服端發送一個連接,確認客服端收到本身發送的報文段
第三次握手: 服務器端確認客服端收到了本身發送的報文段
複製代碼
1.查詢NDS(域名解析),獲取域名對應的IP地址 查詢瀏覽器緩存
2.瀏覽器與服務器創建tcp連接(三次握手)
3.瀏覽器向服務器發送http請求(請求和傳輸數據)
4.服務器接受到這個請求後,根據路經參數,通過後端的一些處理生成html代碼返回給瀏覽器
5.瀏覽器拿到完整的html頁面代碼開始解析和渲染,若是遇到外部的css或者js,圖片同樣的步驟
6.瀏覽器根據拿到的資源對頁面進行渲染,把一個完整的頁面呈現出來
複製代碼
流程:解析html以及構建dom樹 -> 構建render樹 -> 佈局render樹 -> 繪製render樹
概念:1.構建DOM樹: 渲染引擎解析HTML文檔,首先將標籤轉換成DOM樹中的DOM node(包括js生成的標籤)生成內容樹
2.構建渲染樹: 解析對應的css樣式文件信息(包括js生成的樣式和外部的css)
3.佈局渲染樹:從根節點遞歸調用,計算每個元素的大小,位置等。給出每一個節點所在的屏幕的精準位置
4.繪製渲染樹:遍歷渲染樹,使用UI後端層來繪製每個節點
重繪:當盒子的位置、大小以及其餘屬性,例如顏色、字體大小等到肯定下來以後,瀏覽器便把這些顏色都按照各自的特性繪製一遍,將內容呈如今頁面上
觸發重繪的條件:改變元素外觀屬性。如:color,background-color等
重繪是指一個元素外觀的改變所觸發的瀏覽器行爲,瀏覽器會根據元素的新屬性從新繪製,使元素呈現新的外觀
注意:table及其內部元素須要屢次計算才能肯定好其在渲染樹中節點的屬性值,比同等元素要多發時間,要儘可能避免使用table佈局
重排(重構/迴流/reflow): 當渲染書中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建,這就是迴流。
每一個頁面都須要一次迴流,就是頁面第一次渲染的時候
重排必定會影響重繪,可是重繪不必定會影響重排
複製代碼
1.瀏覽器預先加載css後,能夠沒必要等待HTML加載完畢就能夠渲染頁面了
2.其實HTML渲染並不會等到徹底加載完在渲染頁面,而是一邊解析DOM一邊渲染。
3.js寫在尾部,主要是由於js主要扮演事件處理的功能,一方面不少操做是在頁面渲染後才執行的。另外一方面能夠節省加載時間,使頁面可以更加的加載,提升用戶的良好體驗
可是隨着JS技術的發展,JS也開始承擔頁面渲染的工做。好比咱們的UI其實能夠分被對待,把渲染頁面的js放在前面,時間處理的js放在後面
複製代碼
1.indexBD: 是h5的本地存儲庫,把一些數據存儲到瀏覽器中,沒網絡,瀏覽器能夠從這裏讀取數據,離線運用。5m
2.Cookie: 經過瀏覽器記錄信息確認用戶身份,最大4kb,這也就限制了傳輸的數據,請求的性能會受到影響
3.Session: 服務器端使用的一種記錄客戶狀態的機制(session_id存在set_cookie發送到客服端,保存爲cookie)
4.localStroage: h5的本地存儲,數據永久保存在客服端
複製代碼
一、cookie,sessionStorage,localStorage是存放在客戶端,session對象數據是存放在服務器上 實際上瀏覽器和服務器之間僅需傳遞session id便可,服務器根據session-id找到對應的用戶session對象 session存儲數據更安全一些,通常存放用戶信息,瀏覽器只適合存儲通常的數據 二、cookie數據始終在同源的http請求中攜帶,在瀏覽器和服務器來回傳遞,裏面存放着session-id sessionStorage,localStorage僅在本地保存 三、大小限制區別,cookie數據不超過4kb,localStorage在谷歌瀏覽中2.6MB 四、數據有效期不一樣,cookie在設置的(服務器設置)有效期內有效,無論窗口和瀏覽器關閉 sessionStorage僅在當前瀏覽器窗口關閉前有效,關閉即銷燬(臨時存儲) localStorage始終有效
SessionStorage和localStorage區別: 1.sessionStorage用於本地存儲一個會話(session)中的數據,這些數據只有在用一個會話的頁面中才能被訪問(也就是說在第一次通訊過程當中) 而且在會話結束後數據也隨之銷燬,不是一個持久的本地存儲,會話級別的儲存 2.localStorage用於持久化的本地存儲,除非主動刪除數據,不然不會過時
一、token就是令牌,好比你受權(登陸)一個程序時,他就是個依據,判斷你是否已經受權該軟件(最好的身份認證,安全性好,且是惟一的)
用戶身份的驗證方式
二、cookie是寫在客戶端一個txt文件,裏面包括登陸信息之類的,這樣你下次在登陸某個網站,就會自動調用cookie自動登陸用戶名
服務器生成,發送到瀏覽器、瀏覽器保存,下次請求再次發送給服務器(存放着登陸信息)
三、session是一類用來客戶端和服務器之間保存狀態的解決方案,會話完成被銷燬(表明的就是服務器和客戶端的一次會話過程)
cookie中存放着sessionID,請求會發送這個id。sesion由於request對象而產生。
複製代碼
一、用戶經過用戶名和密碼發送請求
二、服務器端驗證
三、服務器端返回一個帶簽名的token,給客戶端
四、客戶端儲存token,而且每次用於發送請求
五、服務器驗證token而且返回數據
每一次請求都須要token
複製代碼
一、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
二、cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙考慮到安全應當使用session。
三、session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能考慮到減輕服務器性能方面,應當使用COOKIE。
四、單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20個cookie。
複製代碼
一、session認證只是把簡單的User的信息存儲Session裏面,sessionID不可預測,一種認證手段。只存在服務端,不能共享到其餘的網站和第三方App
二、token是oAuth Token,提供的是認證和受權,認證針對用戶,受權是針對App,目的就是讓某APP有權訪問某用戶的的信息。Token是惟一的,
token不能轉移到其餘的App,也不能轉到其餘用戶上。(適用於App)
三、session的狀態是存在服務器端的,客戶端只存在session id, Token狀態是存儲在客戶端的
複製代碼
一、數量和長度的限制。每一個特定的域名下最多生成20個cookie(chorme和safari沒有限制)
二、安全性問題。
複製代碼
1、觀察者模式:juejin.im/post/5a14e9… juejin.im/post/5af05d… 在軟件開發設計中是一個對象(subject),維護一系列依賴他的對象(observer),當任何狀態發生改變自動通知他們。強依賴關係 簡單理解:數據發生改變時,對應的處理函數就會自動執行。一個Subjet,用來維護Observers,爲某些event來通知(notify)觀察者
2、發佈-訂閱者 有一個信息中介,過濾 耦合性低 它定義了一種一對多的關係,能夠使多個觀察者對象對一個主題對象進行監聽,當這個主題對象發生改變時,依賴的全部對象都會被通知到。
1.冒泡排序:重複走訪過要排序的數列,一次比較兩個元素,若是他們的順序錯誤就把它們交換過來。
實現過程:1.比較相鄰的元素。若是第一個比第二個大,就交換他們兩個
2.對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數
3.針對全部的元素重複以上的步驟,除了最後一個
4.重複步驟1-3,直到排序完成。
2.選擇排序:首先在未排序序列中找到最小值,放在排序序列的起始位置,而後,在從剩下未排序元素中繼續尋找最小值,而後放在與排序序列的末尾
實現過程:
3.插入排序:構建有序序列,對於未排序數據,在已排序序列中衝後向前掃描,找到相應位置並插入
實現過程:1.從第一個元素開始,該元素能夠認爲已經被排序
2.取出下一個元素,在已排序的元素序列中衝後向前掃描
3.若是該元素(以排序)大於新元素,將元素向後移一位
4.在取出一個元素,比較以前的,直到找到本身合適的位置
4.桶排序:將數據分佈到有限數量的桶裏,每一個桶在分別排序
1.快速排序:快速排序使用分治法把一個串(list)分爲兩個子串(sub-lists).具體算法實現
實現過程:1.從數組中挑出一個元素,成爲一個基準
2.從新排列數組,全部元素比基準小的擺在基準前面,全部元素比基準大的擺在基準後面(相同的能夠擺在一邊)
這個分區退出以後,該基準就處於數列的中間位置。成爲分區操做。
3.遞歸的把小於基準值的子數列和大於基準值元素的子數列排序
算法實現: function quickSort (arr) {
if (arr.length <= 1) {return arr}
var destIndex = Math.floor(arr.length/2)
var left = [], right = [];
var dest = arr.splice(destIndex,1)[0];
for (var i =0;i<arr.length;i++){
if (arr[i]<dest) {
left.push(arr[i])
} else {
right.push(arr[i]) }
return quickSort(left).concat([dest],quickSort(right)
2.堆排序:利用對這種數據結構所涉及的一種排序算法,堆積是一個近乎徹底二叉樹的結構,並同時知足堆積的性質:即子節點的鍵值或索引老是小於(或大於)它的父節點。
實現過程:1.
複製代碼
1.雙重循環
2.indexOf
3.數組排序去重 最快你Olong
複製代碼
判斷迴文字符串:(遞歸的思想)
1.字符串分隔,倒轉,聚合[...obj].reverse().join('')
2.字符串頭部和尾部,逐次向中間檢測
實現:function isPalindrome(line) {
line += '';
for (var i=0,j=line.length-1;i<j;i++,j--) {
if (line.chartAt(i) !== line.chartAt(j) {
return false
}
3.遞歸
複製代碼
二分查找能夠解決已排序數組的查找問題,即只要數組中包含T(要查找的值),那麼經過不斷的縮小包含T的數據範圍,就能夠最終要找到的數
(1) 一開始,數據範圍覆蓋整個數組。
(2) 將數組的中間項與T進行比較,若是T比數組的中間項小,則到數組的前半部分繼續查找,反之,則到數組的後半部分繼續查找。
(3) 就這樣,每次查找均可以排除一半元素,至關於範圍縮小一半。這樣反覆比較,反覆縮小範圍,最終會在數組中找到T
代碼實現:function binarySearch (data, dest, start, end){
var end = end || data.length-1;
var start = start || 0;
var m = Math.floor((start+end)/2);
if (dest<data[m]){
return binarySearch(data, dest, 0, m-1)
} else {
return binarySearch(data, dest, m+1, end)
}}
return false
複製代碼
一句話歸納:1.bind()返回一個新函數,並不會當即執行。
2.bind的第一個參數將做爲他運行時的this,以後的一系列參數將會在傳遞的實參前傳入做爲他的參數
3.bind返回函數做爲構造函數,就是能夠new的,bind時指定的this值就會消失,但傳入的參數依然生效
複製代碼
Function.prototype.bind = function (obj, arg) { var arg = Array.prototype.slice.call(arguments, 1); var context = this; var bound = function (newArg) { arg = arg.concat(Array.prototype.slice.call(newArg); return context.apply(obj, arg) } var F = function () {} // 在new一個bind會生成新函數,必須的條件就是要繼承原函數的原型,所以用到寄生繼承來完成咱們的過程 F.prototype = context.prototype; bound.prototype = new F(); return bound; } 複製代碼
ajax的原理:至關於在用戶和服務器之間加一箇中間層(ajax引擎),使用戶操做與服務器響應異步化。
優勢:在不刷新整個頁面的前提下與服務器通訊維護數據。不會致使頁面的重載
能夠把前端服務器的任務轉嫁到客服端來處理,減輕服務器負擔,節省寬帶
劣勢:不支持back。對搜索引擎的支持比較弱;不容易調試
怎麼解決呢?經過location.hash值來解決Ajax過程當中致使的瀏覽器前進後退按鍵失效,
解決之前被人常遇到的重複加載的問題。主要比較先後的hash值,看其是否相等,在判斷是否觸發ajax
複製代碼
function getData(url) { var xhr = new XMLHttpRequest(); // 建立一個對象,建立一個異步調用的對象 xhr.open('get', url, true) // 設置一個http請求,設置請求的方式,url以及驗證身份 xhr.send() //發送一個http請求 xhr.onreadystatechange = function () { //設置一個http請求狀態的函數 if (xhr.readyState == 4 && xhr.status ==200) { console.log(xhr.responseText) // 獲取異步調用返回的數據 } } } Promise(getData(url)).resolve(data => data) AJAX狀態碼:0 - (未初始化)尚未調用send()方法 1 - (載入)已調用send方法,正在發送請求 2 - (載入完成呢)send()方法執行完成 3 - (交互)正在解析相應內容 4 - (完成)響應內容解析完成,能夠在客戶端調用了 ``` #### 3、函數節流(throttle) ``` function throttle (func, wait) { var timeout; var previous = 0; return function () { context = this; args = arguments; if (!timeout) { timeout = setTimeout(() => { timeout = null; func.apply(context,args) }, wait); } } } } ``` #### 4、函數防抖(dobounce) ``` function debounce (func, wait) { var timeout; return function() { var context = this; var args = arguments; clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context,args) }, wait); } } ``` #### 5、實現一個函數clone,能夠對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值複製 ``` Object.prototype.clone = function() { var newObject = this.constructor === Array ? [] : {} //對象的深拷貝 獲取對應的構造函數 [] 或者 {} for (let e in this) { //遍歷對象的屬性 in this[e] newObject[e] = typeof this[e] === 'object' ? this[e].clone() : this[e] //對象中的屬性若是仍是對象 那就繼續遞歸 不然就返回基本的數據類型 } return newObject } ``` #### 6、實現一個簡單的Promise https://juejin.im/post/5b2f02cd5188252b937548ab ``` class Promise { constructor (executor) { // executor裏面有兩個參數,一個叫resolve(成功),一個叫reject(失敗)。 this.status = 'pending', this.value = undefined; this.reason = undefined; // 成功存放的數組 this.onResolvedCallbacks = []; // 失敗存放法數組 this.onRejectedCallbacks = []; let resolve = (value) => { if (this.status == 'pending') { this.status = 'resolve'; this.value = value; this.onResolvedCallbacks.forEach(fn => fn()) } } let reject = (reason) => { if (this.status == 'pending') { this.status = 'reject'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()) } } try{ executor(resolve, reject); } catch (err) { reject(err); } } then (onFullFilled,onRejected) { if (this.status == 'resolved') { onFullFilled(this.value) } if (this.status == 'rejectd') { onRejected(this.reason); } if (this.status == 'pending') { this.onResolvedCallbacks.push(()=>{ onFullFilled(this.value); }) this.onRejectedCallbacks.push(()=> { onRejected(this.reason); }) } } } const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('hello world') }, 1000); }) p.then((data) =>{ console.log(data) },(err) =>{ console.log(err); }) ``` #### 7、發佈訂閱者模式(觀察者模式) ``` var event = {}; // 發佈者 event.clientList = [] //發佈者的緩存列表 event.listen = function (fn) { // 增長訂閱者函數 this.clientList.push(fn) } event.trigger = function () { // 發佈信息 for (var i =0;i<this.clientList.length;i++) { var fn = this.clientList[i]; fn.apply(this, arguments); } } event.listen (function(time) { console.log('正式上班時間爲:' +time) }) event.trigger ('2018/7') ``` #### 8、手動寫一個node服務器 ``` const http = require('http'); const fs = require('fs'); const server = http.createServer((req,res) => { if (reu.url == '/') { const indexFile = fs.createReadStream('./index.html') req.writeHead(200,{'context-Type':'text/html;charset = utf8}) indexFile.pipe(res) } server.listen(8080)