知識點目錄基於 http://www.javashuo.com/article/p-bwnrhidz-gx.html
根據我的理解對每一個知識點附上的答案,有錯誤歡迎你們指出。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>標題</title> </head> <body> 內容 </body> </html>
header、footer、nav、section文檔中的一節、article頁面的獨立內容區域、aside頁面側邊欄內容、detailes文檔某個細節部分、summary包含details元素的標題、dialog對話框
提供input更多輸入類型,如color、date、email、number、range、tel、week、url、search等;新的表單元素datalist(其id屬性與input的list屬性綁定,實現選項列表輸入);新表單元素keygen、output等;新增placehoder、required、pattern、min、max、step、height、width、autofocus、multiple屬性。
<script> var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.fillStyle="#FF0000"; ctx.fillRect(0,0,150,75); </script> 還有moveTo(x,y)線條開始座標、lineTo(x,y)線條結束座標; fillText(text,x,y)實心文本、strokeText(text,x,y)心文本; createLinearGradient(x,y,x1,y1) - 建立線條漸變 createRadialGradient(x,y,r,x1,y1,r1) - 建立一個徑向/圓漸變 drawImage(image,x,y) - 將圖片放在畫布上等
網絡: 檢測網絡狀態: window.navigator.onLine 事件監聽:online和offline 監聽連上網絡和斷開網絡 地理定位: 獲取當前地理信息: window.navigator.geolocation.getCurrentPosition( successCallback, errorCallback, options ) 重複獲取當前地理信息: window.navigator.geolocation.watchPosition( successCallback, errorCallback, options ) 成功的回調參數: position.coords.latitude 緯度 position.coords.longitude經度 web存儲: sessionStorage(生命週期爲關閉瀏覽器) 5M localStorage(永久生效,除非手動刪除) 20M 全屏: 容許用戶自定義網上任一元素全屏顯示: requestFullScreen() 開啓全屏 cancelFullScreen() 關閉全屏 文件讀取: FileList對象,input上傳文件後返回該對象 FileReader對象: 讀取:readAsDataURL(file.files[0]) 監聽: onload 拖拽: 給元素設置draggable="true",其中img和a標籤默承認拖拽 事件監聽: 拖拽元素: drag: 拖拽過程當中一直調用 dragstart: 拖拽開始調用 dragleave: 鼠標離開拖拽元素調用 dragend: 拖拽結束調用 目標元素: dragenter:拖拽元素進入時調用 dragover:停留在目標元素上時調用,注意阻止瀏覽器默認行爲(event.preventDefault()) drop:當在目標元素上鬆開鼠標時調用 dragleave:當鼠標離開目標元素時調用 能夠經過dataTransfer拿到當前的拖拽進來的文件列表 多媒體: load()、play()、pause()
css3新增的屬性和選擇器: 屬性選擇器、僞類選擇器、反選僞類(:not()) box-shadow、border-image、 text-overflow(clip|ellipsis|string)、word-wrap、border-radius、opacity、 box-sizing、resize、 background-size、background-origin、background-clip transform、trasition、animation
格式化上下文,指一個獨立的渲染區域或者說是一個隔離的獨立容器
將元素類比爲一個盒子,有外邊距、邊框、內邊距、寬度、高度五個元素決定齊所佔的元素空間大小
常見問題:javascript
可經過box-sizing:border-box鎖定元素寬高;
content-box 元素的寬高 = 邊框 + 內邊距 + 內容寬高 border-box 元素的寬高 = width/height的寬高
將其中一個元素放入一個BFC模式的元素內(不推薦,會改變文檔結構);通常會給其中一個元素設置margin-bottom直接給夠距離
利用BFC機制,好比父盒子設置overflow:hidden;
內容寬高 = width/height 元素寬高 = 邊框+內邊距+width/height;設置box-sizing:border-box後值爲:width/height 元素空間的寬高:外邊距+邊框+內邊距+width/height
css預處理器方便開發,無需考慮瀏覽器兼容問題,代碼模塊化、清晰簡潔scss 是 sass3 引入新的語法,其語法徹底兼容 css3,而且繼承了 sass 的強大功能。sass 和 scss 實際上是同一種東西,咱們平時都稱之爲 sass,二者之間不一樣之處有如下兩點:1.文件擴展名不一樣(.sass/.scss);2.語法書寫方式不一樣,sass 是以嚴格的縮進式語法規則來書寫,不帶大括號({})和分號(;),而 scss 的語法書寫和咱們的 css 語法書寫方式很是相似。css
<meta name="viewport" content="width=device-width,initial-scale=1" />
@media screen and (min-width: 768px) and (max-width: 1024px) ...
基本:String、Number、Boolean、Undefined、Null 引用:Object(Array、Function...) 檢測: typeof(用於基本類型;typeof null返回object;typeof []返回object) 變量 === null ? 'null' : typeof 變量 instanceof(用於引用類型;不適用undefined和null) (變量).constructor(不適用undefined和null) Object.prototype.toString.call(),能夠解決判斷全部類型
+運算符的一個值若是是字符串,它會把另外一個值轉爲字符串拼接 一元+,會將值試圖轉爲數字,如 +"5" 一元!,會將值試圖轉爲boolean,再取反 在作比較運算時,也會發生不少隱示轉換: 對象轉字符串再轉數字 布爾轉數字 字符串轉數字
函數定義: function example(param){} const example = function(param){} (function (param){})() const example = new Function('param', '') (param) => {} 箭頭函數內的this與外層的this同樣,箭頭函數不能提高 函數調用: 函數名調用 example(param)至關於window.example(param) 做爲方法調用,好比某個對象中的行爲 obj.example(param) 構造函數調用 const exampleObj = new example(param); exampleObj.屬性/行爲 做爲函數方法調用函數call()、apply(): obj = example.call(obj, param1, param2) obj = example.apply(obj, paramArray)
call和apply詳解: 在javascript中,call和apply都是爲了改變某個函數運行時的上下文(context)而存在的,換句話說,就是爲了改變函數體內部this的指向。 function fruits() {} fruits.prototype = { color: "red", say: function() { console.log("My color is " + this.color); } } var apple = new fruits; apple.say(); //My color is red banana = { color: "yellow" } apple.say.call(banana); //My color is yellow apple.say.apply(banana); //My color is yellow 因此,能夠看出call和apply是爲了動態改變this而出現的,當一個object沒有某個方法(本例子中banana沒有say方法), 可是其餘的有(本例子中apple有say方法),咱們能夠藉助call或apply用其它對象的方法來操做。 兩者區別: func.call(this, arg1, arg2); 若干個參數 func.apply(this, [arg1, arg2]); 數組參數 經常使用實例: 數組追加: var array1 = [12 , "foo" , {name:"Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); // array1 值爲 [12 , "foo" , {name:"Joe"} , -2458 , "Doe" , 555 , 100] 獲取數組中的最大值和最小值: var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math, 5, 458, 120, -215); //458 // number 自己沒有 max 方法,可是 Math 有,咱們就能夠藉助 call 或者 apply 使用其方法。 驗證是不是數組(前提是toString()方法沒有被重寫過): functionisArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ; } 真僞數組轉換: 真轉僞:[].push.apply(obj, arr); 僞轉真:[].slice.call(obj); bind 是返回對應函數,便於稍後調用;apply 、call 則是當即調用
基本類型,按值傳遞(函數內部修改形參值,不會影響外部實參值) 引用類型,按對象共享傳遞 var obj = {}; function f(o) { o.name = 'li'; } f(obj); console.log(obj.name); //li 被修改了 var obj = {}; function f(o) { o = []; } f(obj); console.log(obj); //{} 沒有修改 調用函數傳參時,函數接受對象實參引用的副本(既不是按值傳遞的對象副本,也不是按引用傳遞的隱式引用)。 它和按引用傳遞的不一樣在於:在共享傳遞中對函數形參的賦值,不會影響實參的值。以下面例子中,不能夠經過修改形參o的值,來修改obj的值。 也就是說不能夠改變引用類型的指針,只能夠改變這個對象的屬性
concat()拼接數組,參數是任意個值或者數組,返回新數組,不影響原數組 join()將數組的值用指定分隔符轉成字符串,不傳參默認爲逗號,返回新值,不影響原值 pop()刪除並返回數組最後一個元素 push()向數組末尾添加一個或多個元素,返回數組新長度 shift()刪除並返回數組第一個元素 unshift()想數組開頭添加一個或多個元素,返回數組新長度 slice(start,end)包含頭不包含尾,返回新值對原值沒有影響 splice(index,howmany,item1...,itemX) 可用於替換,刪除,添加; howmany表示要刪除的個數,返回被刪除的值組成的數組,原數組被修改 sort()對數組元素排序,修改原值 reverse()點到數組中元素的順序,修改原值 every()是對數組中的每一項運行給定函數,若是每一項都返回true,則返回true some()是對數組中的每一項運行給定函數,若是對任一項返回true,則返回true filter()是對數組中的每一項運行給定函數,返回該函數返回true的項組成數組 map()是對數組中的每一項運行給定函數,返回每次函數調用的結果組成數組 reduce()從數組元素中計算出一個值 arr.indexOf('')查找數組,判斷數組中是否含有某一項
三個字符方法: charAt()返回給定位置的字符 charCodeAt()返回給定位置的字符編碼 str[index]直接用方括號加索引也能返回指定位置的字符,IE7及更早版本不支持 操做字符串方法: concat()用於拼接字符串,可傳任意個參數 slice(start,end)包含頭不包含尾,返回新值對原值沒有影響 substring(start,end)包含頭不包含尾,返回新值對原值沒有影響 substr(start,num)第二個參數爲個數,返回新值對原值沒有影響 字符串位置方法: indexOf()從前日後找、lastIndexOf()從後往前找 大小寫: toLowerCase()、toLocaleLowerCase()、toUpperCase()、toLocaleUpperCase() 都是返回新值對原值沒有影響 字符串的模式匹配方法: match()參數爲正則表達式或者RegExp對象,返回匹配的數組 search()返回字符串中第一個匹配項的索引,若是沒找到就返回-1 replace(egexp/substr, replacement/function),返回新值對原值沒有影響 split()基於分隔符分割字符串,返回新數組對原值沒有影響 trim()刪除字符串先後全部空格,返回新值對原值沒有影響
格式:/正則表達式主體/修飾符(可選) \d: 0-9任意一個數字 \w: 數字、字母、下劃線 0-9 a-z A-Z _ \s: 空格或者空白 (): 分組 [a-z]: 區間內任意一個 *: 0到多個 +: 1到多個 {n}: 正好n次 {n,m}: n-m次 好比手機:/1[34578]\d{9}/
全局做用域、函數做用域 ES6引入let和const關鍵字,隨即帶來塊級做用域的概念
對象有一個內部屬性[[Scope]],該屬性包含了函數被建立的做用域中對象的集合,這個集合被稱爲函數的做用域鏈。 js解析某個變量時,會從代碼嵌套的最內層開始,若是沒找到,會順着做用域鏈向上查找。
函數內部返回一個函數 對外部暴露指定行爲,但仍是能用到本身做用域內的變量 function greet(){ name = 'Alan'; return function() { console.log('Hi ' + name); } } greet()(); 私有做用域 (function () { // private scope )() 模塊模式 var Module = (function () { function _privateMethod() {} return { publicMethod: function() { // can call privateMethod(); } } })()
構造函數的prototype指向一個原型對象, 原型對象的constructor指回構造函數, 實例的內部指針__proto__指向原型對象。 經過調用構造函數產生的實例,都有一個內部屬性,指向了原型對象。因此實例可以訪問原型對象上的全部屬性和方法 例子: function Dog (name) { this.name = name; } Dog.prototype.speak = function () { alert('wang'); } var doggie = new Dog('jiwawa'); doggie.speak(); //wang Dog.prototype.constructor == Dog //true
graph LR C[實例] --> B A[構造函數Dog] --> B[Dog的原型對象] B --> A
//定義一個 Animal 構造函數,做爲 Dog 的父類 function Animal () { this.superType = 'Animal'; } Animal.prototype.superSpeak = function () { alert(this.superType); } function Dog (name) { this.name = name; } //改變Dog的prototype指針,指向一個 Animal 實例 Dog.prototype = new Animal(); Dog.prototype.speak = function () { alert(this.type); } var doggie = new Dog('jiwawa'); doggie.superSpeak(); //Animal 若是將Dog的prototype指針指向另外一個Animal的實例,那麼Dog的實例就能調用Animal的屬性和方法。
規律一:函數名加圓括號直接調用,函數上下文是 window 對象。 規律二:函數若是做爲一個對象的方法,對象使用點方法進行調用,那麼函數的上下文就是這個對象。 規律三:函數是事件處理函數,那麼函數的上下文就是觸發這個事件的對象。 規律四:函數被定時器調用時,上下文是 window 對象。 規律五:數組中存放的函數,被數組索引調用,函數上下文就是這個數組。
JS單線程(主線程) ↓ 單線程致使任務須要排隊,若是前一個任務耗時很長,後面的就一直等着。 若是排隊是由於計算了大,CPU忙不過來,倒也算了。 不少時候沒事由於IO設備慢(好比Ajax操做從網絡讀取數據) ↓ 同步任務和異步任務 同步:在主線程上排隊執行的任務,前一個完成,才執行後一個。 異步:不進入主線程,而進入「任務隊列」,只有「任務隊列」通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。 只要主線程空了,就會去讀取"任務隊列",這就是JavaScript的運行機制。這個過程會不斷重複 ↓ "任務隊列"是一個事件(消息)的隊列,IO設備完成一項任務,就在"任務隊列"中添加一個事件,表示相關的異步任務能夠進入"執行棧"了。主線程讀取"任務隊列",就是讀取裏面有哪些事件。 "任務隊列"中的事件,除了IO設備的事件之外,還包括一些用戶產生的事件(好比鼠標點擊、頁面滾動等等)。只要指定過回調函數,這些事件發生時就會進入"任務隊列",等待主線程讀取。 所謂"回調函數"(callback),就是那些會被主線程掛起來的代碼。異步任務必須指定回調函數,當主線程開始執行異步任務,就是執行對應的回調函數。 主線程的讀取過程基本上是自動的,只要執行棧一清空,"任務隊列"上第一位的事件就自動進入主線程。可是,因爲"定時器"功能,主線程首先要檢查一下執行時間,某些事件只有到了規定的時間,才能返回主線程。 ↓ 主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,因此整個的這種運行機制又稱爲Event Loop(事件循環)。 執行棧中的代碼(同步任務),老是在讀取"任務隊列"(異步任務)以前執行。
Ajax 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。 var xmlHttp; if (window.XMLHttpRequest) {// IE7及以上 xmlHttp = new XMLHttpRequest(); } else { xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); } xmlHttp.open('GET/POST', url, true/false); // 若是是post,須要設置請求頭 xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xmlHttp.send(); // 若是是post,須要傳參數,參數爲空就傳null; xmlHttp.onreadystatechagne = function() { if (xmlHttp.readyState == 4) { if (xmlHttp.status >= 200 && xmlHttp.status < 300 || xmlHttp.status == 304) { // 成功回調函數... } else { // 失敗回調函數... } } }; 相關知識點: GET 更簡單更快,沒法發送大數據,沒法緩存 POST 更大更穩定,可發大數據,可緩存 readyState(0: 請求未初始化 1: 服務器鏈接已創建 2: 請求已接收 3: 請求處理中 4: 請求已完成,且響應已就緒) status(1字頭:消息,表明請求已被接受,須要繼續處理; 2字頭:成功; 3字頭:重定向; 4字頭:請求錯誤; 五、6字頭:服務器錯誤) 常見:200成功、304緩存、404未找到頁面、500服務器錯誤
普通使用: import axios from 'axios' axios.get/post(url, params).then(function(){}).catch(function(){}) 自定義axios常見使用方式: let myAxios = axios.create({ baseURL: '', timeout: 30000, headers: {}, ... }) // 請求攔截器 myAxios.interceptors.request.use( function (config) { // 發送請求以前作些什麼,好比token if (store.state.Token) { config.headers.Authorization = '前綴' + store.state.Token } reutrn config }, function (error) { // 對請求錯誤,作些什麼 return Promise.reject(error) } ) // 響應攔截器 myAxios.interceptors.response.use( function (response) { // 對響應數據作點什麼 return response.data }, function (error) { // 對響應錯誤作點什麼, 好比後臺返回token失效的狀態碼,就須要跳轉login if (error && error.response) { switch (error.response.status) { case 400: error.message = '請求出錯' break case 401: alert('token失效,從新登陸') store.commit('loginOut') setTimeout(() => { window.location.reload() }, 1000) return } } else { error.message = '鏈接服務器失敗' } alert(error.message) return Promise.reject(error.response) } )
Trident(IE)、Gecko9(火狐)、Blink(Chrome、Opera)、Webkit(Safari)html
HTML解釋器 CSS解釋器 圖層佈局計算模塊:佈局計算每一個對象的精確位置和大小 視圖繪製模塊:進行具體節點的圖像繪製,將像素渲染到屏幕上 JavaScript引擎:編譯執行JS代碼
運行機制: 瀏覽器使用http/https向服務的請求頁面 ↓ 解析HTML,構建DOM樹 ↓ 計算DOM樹上的CSS ↓ (排版)根據CSS屬性渲染元素,獲得內存中的位圖 ↓ (可選步驟)對位圖進行合成,提高後續繪製速度 ↓ 繪製到界面上
解析HTML,生成DOM樹(DOM) 解析CSS,生成CSSOM樹(CSSOM) 將DOM和CSSOM合併,生成渲染樹(Render-Tree) 計算渲染樹的佈局(Layout) 將佈局渲染到屏幕上(Paint)
JavaScript分三個部分: ECMAScript標準 --- 基本語法 DOM --- 文檔對象模型,操做頁面元素的 BOM --- 瀏覽器對象模型,操做瀏覽器的 瀏覽器頂級對象: window 頁面頂級對象: document 頁面中全部內容都屬於瀏覽器
BOM是獨立於內容的、能夠與瀏覽器窗口進行互動的對象結構,其由多個對象組成,其中表明瀏覽器窗口的Window對象是其頂層對象。 可刷新瀏覽器、後退、前進、在瀏覽器中輸入URL等。 alert()、prompt()、confirm() onload()、onunload() setTimeout()、clearTimeout()、setInterval()、clearInterval() loaction、history、navigator
document. getElementById() getElementsByTagName() getElementsByName() getElementsByClassName() querySelector() createElement() appendChild()
addEventListener("事件名","事件處理函數","布爾值false冒泡,true捕獲") removeEventListener("事件名","事件處理函數","布爾值") preventDefault()阻止默認事件 stopPropagation()阻止事件冒泡 其餘經常使用事件: onclick、ondbclick、 onmousedown、onmouseup、onmouseout、onmousemove、onmouseover
原理:利用事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件 window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ alert(target.innerHTML); } } }
強緩存:用戶發送的請求,直接從客戶端緩存中獲取,不發送請求到服務器,不與服務器發生交互行爲。 協商緩存:用戶發送的請求,發送到服務器後,由服務器斷定是否從緩存中獲取資源。 二者共同點:客戶端得到的數據最後都是從客戶端緩存中得到。 二者的區別:從名字就能夠看出,強緩存不與服務器交互,而協商緩存則須要與服務器交互。
爲何會跨域:瀏覽器的同源策略(阻止不一樣協議或者域名或者端口的請求) 解決方法: JSONP(只能發GET請求) 空iframe加form CORS(跨域資源共享):響應頭設置Access-Control-Allow-Origin等... 代理 ...
HTTP(Hyper Text Transfer Protocol)超文本傳輸協議: 基於TCP/IP通訊協議傳遞數據,用於從萬維網服務器傳輸超文本到本地瀏覽器的傳送協議 主要特色: 簡單快速、靈活、無鏈接(完成請求就斷開連接)、無狀態、支持B/S C/S
HTTP使用統一資源標識符URI來傳輸數據和創建鏈接,統一資源定位符URL是URI的一種特殊類型 URL:協議+域名+端口+虛擬目錄+文件名+錨(#)+參數(?)
請求行(請求方法 URL 協議版本) 請求頭(頭部字段名 值...) 空行(必定有一個空行)請求數據 請求數據
狀態行(協議版本 狀態碼 狀態消息) 消息報頭 空行 響應正文(服務器返回給客戶端的文本信息)
1xx:指示信息--表示請求已接收,繼續處理 2xx:成功--表示請求已被成功接收、理解、接受 3xx:重定向--要完成請求必須進行更進一步的操做 4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現 5xx:服務器端錯誤--服務器未能實現合法的請求 常見: 200 OK:客戶端請求成功 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解 401 Unauthorized:請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用 403 Forbidden:服務器收到請求,可是拒絕提供服務 404 Not Found:請求資源不存在,eg:輸入了錯誤的URL 500 Internal Server Error:服務器發生不可預期的錯誤 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
創建TCP鏈接(三次握手),客戶端鏈接服務器 ↓ 發送HTTP請求 ↓ 服務器接受請求,返回HTTP響應 ↓ 釋放TCP鏈接 ↓ 瀏覽器解析HTML內容
GET: 請求數據附在URL後,地址欄可見 POST: 請求數據包在請求體中 GET: 長度有限(2083字節) POST: 理論上不限制大小,服務器常會對POST數據大小進行限制 GET: 數據明文,不安全 POST: 安全
客戶端緩存技術 瀏覽器的一種數據存儲功能,由服務器生成,發送給瀏覽器,以鍵值方式存儲,下次請求,會把cookie發送給服務器,過時時長由expire決定
會話緩存技術 相似客戶端的身份標識,由服務器生成,保存在服務器端,以鍵值方式存儲,默認30分鐘過時 客戶端每次像服務器發送請求,都帶上身份標識,服務器就知道請求來自誰。客戶端經常使用cookie方式保存標識
用戶登陸成功,服務器生成Token返回給客戶端 客戶端保存Token 客戶端每次請求攜帶Token 服務器校驗Token
生命週期永久,除非手動清楚,存放大小通常5MB,存在客戶端
當前會話有效,關閉瀏覽器清楚,存放大小5MBD,存在客戶端
變量名不自動提示,提供塊級做用域
() => {} 箭頭函數中沒有this,若是在箭頭函數內使用this,該this是外層的this
使用``將字符串包裹,在其中可使用${}來包裹一個變量或表達式
數組以序列號對應,對象根據屬性名對應 eg: // es5 var loading = props.loading; var clicked = props.clicked; // es6 const { loading, clicked } = props; // es6 const arr = [1, 2, 3]; const [a, b, c] = arr; // es5 var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2];
// es5 function add(x, y) { var x = x || 20; var y = y || 30; return x + y; } console.log(add()); // es6 function add(x = 20, y = 30) { return x + y; } console.log(add());
使用...能夠將數組或者對象進行展開 const arr1 = [1, 2, 3]; const arr2 = [...arr1, 10, 20, 30]; // 這樣,arr2 就變成了[1, 2, 3, 10, 20, 30]; const obj1 = { a: 1, b: 2, c: 3 } const obj2 = { ...obj1, d: 4, e: 5, f: 6 } // 結果相似於 const obj2 = Object.assign({}, obj1, {d: 4})
當屬性與值同名時,可簡寫 const person = { name, age } // ES5 // 構造函數 function Person(name, age) { this.name = name; this.age = age; } // 原型方法 Person.prototype.getName = function() { return this.name } // ES6 class Person { constructor(name, age) { // 構造函數 this.name = name; this.age = age; } getName() { // 原型方法 return this.name } } extends繼承關鍵字、super()
解決異步回調地獄問題 promise.then(function(value) { // success 成功回調 }, function(error) { // failure 失敗回調 }); then方法返回一個新的Promise實例,所以支持鏈式寫法,後面的then會等待前面then返回的Promise對象狀態發生變化,而後決定調用resolve仍是reject。 .catch() .finally() ES2018引入, 無論promise最後狀態,都會執行 .all()將多個Promise實例包裝成一個新的Promise實例,只有子實例狀態都變爲fulfilled,包裝實例才變爲fulfilled,若是其中一個是rejected,那麼包裝也是rejected。 .race()同all()方法,至關於或操做,只要有一個實例狀態改變,包裝實例就會跟着改變 .resolve()將現有對象轉爲Promise對象 .reject()返回一個狀態爲rejected的Promise實例
Set相似於數組,但其成員的值都是惟一的,沒有重複的值 const s = new Set() const s1 = new Set([1,2,3,2,3]) [...s] add(value):添加某個值,返回 Set 結構自己。 delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。 has(value):返回一個布爾值,表示該值是否爲Set的成員。 clear():清除全部成員,沒有返回值。
相似於對象,也是鍵值對的集合,可是鍵不限於字符串,各類類型均可以看成鍵。 const map = new Map() map.set(鍵,值) map.get(鍵) map.has(鍵) map.delete(鍵) map.clear() map.size 遍歷Set和Map: keys():返回鍵名的遍歷器。 values():返回鍵值的遍歷器。 entries():返回全部成員的遍歷器。 forEach():遍歷 Map 的全部成員 因爲 Set 結構沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),因此keys方法和values方法的行爲徹底一致
在目標對象以前架設一層「攔截」,外界訪問該對象,都必須先經過這層攔截 var proxy = new Proxy(target, handler) eg: var obj = new Proxy({}, { get: function (target, key, receiver) { console.log(`getting ${key}!`); return Reflect.get(target, key, receiver); }, set: function (target, key, value, receiver) { console.log(`setting ${key}!`); return Reflect.set(target, key, value, receiver); } }); get(target, propKey, receiver): 攔截對象屬性的讀取,好比proxy.foo和proxy['foo']。 set(target, propKey, value, receiver): 攔截對象屬性的設置,好比proxy.foo =v或proxy['foo']=v,返回一個布爾值。 has(target, propKey): 攔截propKey in proxy的操做,返回一個布爾值 ...
Iterator做用: 1. 爲各類數據結構,提供一個統一的訪問接口 2. 使數據結構的成員可以按某種次序排列 3. 創造了一種新的遍歷命令for...of 遍歷器原理:建立一個指針指向數據結構(Array/Set/Map/String/TypedArry/arguments/NodeList)的初始位置, 第一次調用指針對象的next方法,將指針指向第一個成員,第二次next指向第二個,以此類推,直到結束位置。 for(let val of 數據結構){}
export與export default都可用於導出常量、函數、文件、模塊等 在一個文件或模塊中,export、import能夠有多個,export default僅有一個 經過export方式導出,在導入時要加{ },export default則不須要 export能直接導出變量表達式,export default不行
v-text:綁定元素的文本內容 <span v-text="txt"></span> v-html:綁定元素的innerHTML <div v-html="html"></div> v-show:顯示與隱藏,切換元素的display CSS屬性 v-if:Dom元素的銷燬和重建 v-for v-on:綁定事件監聽器,縮寫@;使用:v-on:click="handleClick()" 修飾符: .stop - 調用 event.stopPropagation()。 .prevent - 調用 event.preventDefault()。 .capture - 添加事件偵聽器時使用 capture 模式。 .self - 只當事件是從偵聽器綁定的元素自己觸發時才觸發回調。 .{keyCode | keyAlias} - 只當事件是從特定鍵觸發時才觸發回調。好比 @click.enter="handleEnter" .native - 監聽組件根元素的原生事件。 .once - 只觸發一次回調。 .left - (2.2.0) 只當點擊鼠標左鍵時觸發。 .right - (2.2.0) 只當點擊鼠標右鍵時觸發。 .middle - (2.2.0) 只當點擊鼠標中鍵時觸發。 .passive - (2.3.0) 以 { passive: true } 模式添加偵聽器 v-bind:動態綁定一個或多個特性或組件prop到表達式,縮寫":"; 好比 :class="{}" 修飾符: .prop - 被用於綁定 DOM 屬性 (property)。(差異在哪裏?) .camel - (2.1.0+) 將 kebab-case 特性名轉換爲 camelCase. (從 2.1.0 開始支持) .sync (2.3.0+) 語法糖,會擴展成一個更新父組件綁定值的 v-on 偵聽器。 v-model:數據雙向綁定 修飾符: .lazy - 取代 input 監聽 change 事件 .number - 輸入字符串轉爲有效的數字 .trim - 輸入首尾空格過濾 v-slot:用於<template>,縮寫# v-pre:跳過這個元素和其子元素的編譯過程 v-cloak:與CSS規則[v-cloak]{display:none}一塊兒使用 v-once:只渲染元素和組件一次。<span v-once>This will never change: {{msg}}</span>
經常使用: vm.$refs:返回Object,獲取註冊過ref特性的全部DOM元素和組件實例 其餘: vm.$data:Object,訪問Vue實例的data屬性 vm.$props:Object,訪問Vue實例的props屬性 vm.$el:Element,當前組件的根DOM元素 vm.$options:Object,訪問Vue的初始化選項 vm.$parent:獲取父實例 vm.$root:當前組件樹的根實例 vm.$children vm.$slots:訪問具名插槽的內容 vm.$scopedSlots:訪問做用域插槽的內容 vm.$isServer vm.$attrs vm.$listeners
經常使用: vm.$emit(eventName,[...args]):觸發當前實例上的事件,經常使用於父子組件通訊 vm.$watch:觀察 Vue 實例變化的一個表達式或計算屬性函數 vm.$watch('a.b.c', function (newVal, oldVal) { // 作點什麼 }) vm.$set(target,key,value) 其餘: vm.$delete(target,key) vm.$on(event,callback):監聽當前實例上的自定義事件 vm.$once(event,callback):監聽自定義事件,只觸發一次,觸發後自動移除監聽器 vm.$off([event,callback]):移除自定義事件 vm.$mount([elementOrSelector]):可用於給vue實例手動掛載dom元素 vm.$forceUpdate():迫使vue實例從新渲染 vm.$nextTick([callback]):將回調延遲到下次DOM更新循環以後執行。在修改數據以後當即使用它,而後等待 DOM 更新 vm.$destory():徹底銷燬一個實例。清理它與其它實例的鏈接,解綁它的所有指令及事件監聽器
beforeCreate 實例初始化以後調用 created 實例建立完成後被當即調用 beforeMount 掛載開始以前被調用 mounted 掛載到實例上去以後調用該鉤子 beforeUpdate 數據更新時調用,發生在虛擬 DOM 打補丁以前 updated 因爲數據更改致使的虛擬DOM從新渲染和打補丁,在這以後會調用該鉤子 activated keep-alive組件激活時調用 deactivated keep-alive組件停用時調用 beforeDestory 實例銷燬以前調用 destoryed 實例銷燬後調用 errorCaptured 當捕獲一個來自子孫組件的錯誤時被調用
全局註冊: Vue.component('name', { data () { return { ... } }, template: `<button>BTN</button>` ... }) 局部註冊: var componentA = {} var componentB = {} var componentC = {} new Vue({ el: '#app', components: { componentA, componentB } })
父給子傳值: 直接以屬性的方式,若是是動態值能夠用v-bind,子組件經過props接受值 子給父傳值: 經過自定義事件。 子組件經過$emit('faterEvent', ...params)觸發父組件的自定義事件,父組件自定義事件觸發一個自定義方法,其參數就是子組件傳過來的值。
可藉助同一個父組件通訊
vuex
定義: <slot name="header"></slot> 調用: <template v-slot:header> <h1>Here might be a page title</h1> </template>
讓插槽內容可以訪問子組件中才有的數據 定義: <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span> 調用: <current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>
HTML: 入口(聲明式): <router-link to="/index"></router-link> 出口: <router-view></router-view> JavaScript: import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) // 定義路由 const routes=[ {path: '/index', component: ()=>require('../index')} ] // 建立router實例並配置路由 const router = new Router({ routes }) // 根實例配置router const app = new Vue({ router })
能夠在任何組件內經過this.$router訪問路由器,經過this.$route訪問當前路由。
eg: 將不一樣id的用戶都指向User組件 const router = new Router({ routes: [ // 動態路徑參數,以冒號開頭 {path: '/user/:id', component: User} ] }) 屢次路由若是渲染同個組件,組件會被複用,因此生命週期鉤子不會再調用,可使用watch監聽$route對象。 watch: { '$route': (to, from) {} }
通配符(*): path: '*' path: 'user-*' 若是使用通配符,$route.params會自動添加一個名爲pathMatch參數 // 給出一個路由 { path: '/user-*' } this.$router.push('/user-admin') this.$route.params.pathMatch // 'admin' // 給出一個路由 { path: '*' } this.$router.push('/non-existing') this.$route.params.pathMatch // '/non-existing'
Vue實例內部使用this.$router訪問 router.push(location, onComplete?, onAbort?) eg: // 字符串 router.push('home') // 對象 router.push({ path: 'home' }) // 命名的路由,若是提供了path,params會被忽略 router.push({ name: 'user', params: { userId: '123' }}) // 帶查詢參數,變成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }}) router.replace(location, onComplete?, onAbort?) router.go(n): 向前或後退多少步
全局前置守衛: const router = new Router({ ... }) router.beforeEach((to, from, next) => { // 確保調用next方法,不然鉤子不會被resolved // next() 進行下一個鉤子 // next(false) 中斷當前的導航 // next('/')或者next({path: '/'}) 中斷當前導航,跳轉到新導航 // next(error) 終止導航,並觸發router.onError()的回調 }) 全局解析守衛: router.beforeResolve與上面的前置守衛相似 區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用 全局後置鉤子: router.afterEach((to, from) => {}) 路由獨享的守衛: const router = new Router({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => {} } ] }) 組件內的守衛: export default { name: 'Foo', beforeRouteEnter(to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 // 能夠經過傳一個回調給 next來訪問組件實例。在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數 next(vm => { // 經過 `vm` 訪問組件實例 }) }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` } }
meta: { requiresAuth: true } 訪問元信息: 路由是能夠嵌套的,所以一個路由匹配成功後,可能匹配多個路由記錄 $route.matched數組 router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } else { next() // 確保必定要調用 next() } })
const router = new Router({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 指望滾動到哪一個的位置 return { x: 0, y: 0 } } })
const Home = () => import('@/pages/home/Home') (resolve) => require(['pages/marketing-center/mission-medal/mission-rules/mission-rules'], resolve)
State、Getter、Mutation、Action、Modulevue
爲何要用vuex: 當多個組件共享狀態時(多個視圖依賴同一狀態,不一樣視圖的行爲須要變動同一狀態) vuex和單純的全局對象有兩點不一樣: 1.vuex的存儲是響應式的,當vue組件從store中讀取狀態時,若store中的狀態發生變化,那麼相應的組件也會獲得高效更新。 2.不能直接改變store中的狀態。改變狀態的惟一途徑就是顯示提交mutation。 const store = new Vuex.Store({ state: { count: 0 }, mutation: { increment(state) { state.count++ } } }) const app = new Vue({ el: '#app', store }) this.$store.state.count this.$store.commit('increment')
import { mapState } from 'vuex' export default { computed: { ...mapState(['count']) } }
就像計算屬性同樣,getter的返回值會根據它的依賴被緩存起來,且只有當依賴值發生了改變纔會被從新計算。 const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } } }) 經過屬性訪問: this.$store.getters.doneTodos 經過方法訪問: 定義時返回一個函數: getters: { getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } 訪問時能夠傳參數查詢: this.$store.getters.getTodoById(2)
更改vuex的store中狀態的惟一方法是提交mutation mutation必須是同步函數 const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { state.count++ } } }) this.$store.commit('increment') 或者 methods: { ...mapMutations([ // 將 `this.increment()` 映射爲 `this.$store.commit('increment')` 'increment' ]) }
Action相似於mutation,不一樣在於: Action提交的是mutation,而不是直接變動狀態 Action能夠包含任意異步操做 const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { // 能夠異步操做 setTimeout(() => { context.commit('increment') }, 1000) } } }) 分發Action: this.$store.dispatch('increment') 或者 methods: { ...mapActions(['increment']) }
因爲使用單一狀態樹,當應用變得複雜時,store對象會很是臃腫。 所以,vuex容許咱們將store分割成模塊(module),每一個模塊擁有本身的state、mutation、action、getter、以及嵌套子模塊。 const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) this.$store.state.a // -> moduleA 的狀態 this.$store.state.b // -> moduleB 的狀態
var fs = require('fs') fs.readFile('文件名', 'utf-8', function(err, data){}) fs.readFileSync('文件名', 'utf-8') fs.writeFile('輸出文件名', data, function(err){}) fs.writeFile('輸出文件名', data) fs.stat('文件名', function(err, stat){ if (err) { } else { // 是不是文件: console.log('isFile: ' + stat.isFile()); // 是不是目錄: console.log('isDirectory: ' + stat.isDirectory()); if (stat.isFile()) { // 文件大小: console.log('size: ' + stat.size); // 建立時間, Date對象: console.log('birth time: ' + stat.birthtime); // 修改時間, Date對象: console.log('modified time: ' + stat.mtime); } } })
var fs = require('fs') // 打開一個流 var rs = fs.createReadStream('文件名', 'uft-8') rs.on('data', function(chunk){}) // data可能有屢次,每次傳遞的chunk是流的一部分 rs.on('end', function(){}) rs.on('error', function(err){}) // 用流寫入文件 var ws = fs.createWriteStream('輸出文件名', 'utf-8') ws.write('文本數據。。。') ws.write(newBuffer('用流寫二進制數據', 'utf-8') ws.end() // 用流複製 var rs = fs.createReadStream('sample.txt'); var ws = fs.createWriteStream('copied.txt'); rs.pipe(ws);
var http = require('http'); // 建立http server,並傳入回調函數: var server = http.createServer(function (request, response) { // 回調函數接收request和response對象, // 得到HTTP請求的method和url: console.log(request.method + ': ' + request.url); // 將HTTP響應200寫入response, 同時設置Content-Type: text/html: response.writeHead(200, {'Content-Type': 'text/html'}); // 將HTTP響應的HTML內容寫入response: response.end('<h1>Hello world!</h1>'); }); // 讓服務器監聽8080端口: server.listen(8080);
對http有封裝,使用Promise並配合async來實現異步。 // 導入koa,和koa 1.x不一樣,在koa2中,咱們導入的是一個class,所以用大寫的Koa表示: const Koa = require('koa'); // 建立一個Koa對象表示web app自己: const app = new Koa() // 對於任何請求,app將調用該異步函數處理請求: app.use(async (ctx, next) => { await next(); ctx.response.type = 'text/html'; ctx.response.body = '<h1>Hello, koa2!</h1>'; }); // 在端口3000監聽: app.listen(3000);
const Koa = require('koa'); // 注意require('koa-router')返回的是函數: const router = require('koa-router')(); const app = new Koa(); // log request URL: app.use(async (ctx, next) => { console.log(`Process ${ctx.request.method} ${ctx.request.url}...`); await next(); }); // add url-route: router.get('/hello/:name', async (ctx, next) => { var name = ctx.params.name; ctx.response.body = `<h1>Hello, ${name}!</h1>`; }); router.get('/', async (ctx, next) => { ctx.response.body = '<h1>Index</h1>'; }); // add router middleware: app.use(router.routes()); app.listen(3000); console.log('app started at port 3000...');
const Koa = require('koa'); const app = new Koa(); const bodyParser = require('koa-bodyparser'); app.use(bodyParser());
//引入數據庫 var mysql=require('mysql'); //實現本地連接 var connection = mysql.createConnection({ host: 'localhost', user: 'user', password: '123456', database: 'test' }) connection.query('SELECT * FROM users WHERE id = ?', ['123'], function(err, rows) {}); connection.query("INSERT INTO demo SET ?", post, function (error, results, fields) {}) ...
const Sequelize = require('sequelize'); // 鏈接數據庫 let sequelize = new Sequelize(config.database, config.username, config.password, { host: config.host, dialect: config.dialect, pool: config.pool }); sequelize.define(tableName, attrs, { tableName, timestamps: false, freezeTableName: true, // 鉤子函數,統一設置id、createdAt等這些基礎字段的值 hooks: { beforeValidate: function (obj) { let now = Date.now(); if (obj.isNewRecord) { if (!obj.id) { obj.id = generateId(); } obj.createdAt = now; obj.updatedAt = now; obj.version = 0; obj.isDelete = false; } else { obj.updatedAt = Date.now(); obj.version++; } } } });