11.函數拓展 1) 函數簡寫 1. 函數在對象中 let obj = { sayName(){ }, sayAge(){ }, foo:()=>{}, //不推薦寫法! bar:function(){} } 2. 函數在參數中(回調函數) list.filter(function(item){ return item.gender === "male" }) 等價於 list.filter(item=>item.gender === "male") 等價於 function foo(){ list.filter((item)=>{ //這個箭頭函數中的this指向foo中的this return item.gender === "male" }) } let obj = { data:{ name:"charles", list:[ {name:"larry",gender:"male"}, {name:"tom",gender:"male"}, {name:"vicky",gender:"female"} ], boys:[] }, foo(){ // this指向obj let that = this; this.data.list.forEach(function(item){ //this if(item.gender === "male"){ that.data.boys.push(item) } }) }, bar(){ this.data.list.forEach((item)=>{ //箭頭函數中的this指向外部函數的this if(item.gender === "male"){ this.data.boys.push(item); } }) } } //obj.foo(); obj.bar(); console.log(obj.data.boys); 12. rest操做符 ... 剝離、拆分 let o1 = { a:"1", b:"2" } let o2 = { c:"3", d:"4", e:"5" } Object.assign({},o1,o2) {...o1,...o2} 將字符串轉換數組 let str = "hello"; let arr = [...str] str.split("") 13. 集合的新特性 存放多個值的容器 1) Array 元素有序而且能夠重複的便可 Array.from(v) v爲類數組對象或可迭代的對象(具備迭代器的對象) let al = {"0":"terry","1":"larry","2":"tom",length:3} console.log(al); console.log(Array.from(al)); Array.of() let array = Array.of(2) //[2] let array = Array.of(2,3,4) //[2,3,4] Array.prototype.fill() Array.prototype.includes() Array.prototype.find(匿名函數) Array.prototype.findIndex(匿名函數) 查找到第一個符合條件的值進行返回,與filter相似 Array.prototype.keys() 獲取遍歷key值的迭代器 Array.prototype.values() 獲取遍歷val的迭代器 Array.prototype.entries() 獲取遍歷鍵值對的迭代器 let arr = [ {name:"terry", gender:"male"}, {name:"larry", gender:"male"}, {name:"vicky", gender:"female"} ] let k_iterator = arr.keys(); // 如何利用k_iterator獲取arr中的每一個元素 let item ; while(!(item = k_iterator.next()).done){ let key =item.value; let val = arr[key]; console.log(val); } 2) Set 元素無序不能夠重複的集合 1. 實例化 let s1 = new Set() let s2 = new Set([1,2,3,4,1,2]) 參數必須是能夠迭代的 2. Set.prototype.xxx size add(v) delete(v) has(v) clear() forEach() keys() 獲取值的迭代器 values() 獲取值的迭代器 entries() 獲取值-值的迭代器 3) Map 鍵值對,鍵能夠爲任意數據類型;與對象對比其特色爲key能夠爲任意數據類型 1. 實例化 let map = new Map(); let map = new Map([["name","terry"],["age",12]]) 2. Map.prototype.xxx size set(key,val) key值若是相同,後者覆蓋前者 get(key) has(key) delete(key) clear() forEach() keys() values() entries() 3. 典型應用(購物車) Map { id:{ id, name, price, number } } 加入購物車: { id:1, name:"可口可樂", price:2.5 number:1 } 先判斷購物車中是否具備id爲1的key,若是有,修改number,若是沒有set let shopcar = { car:new Map(), add(line){ if(this.car.has(line.id)){ this.car.get(line.id).number += line.number; }else { this.car.set(line.id,line) } }, remove(id){ this.car.delete(id) }, jiezhang(){ let total = 0; for(let i of this.car.values()){ total += (i.price * i.number) } return total; } } // 首次向購物車中添加可口可樂 shopcar.add({id:1,name:"可口可樂",price:2.5,number:1}) // 再向購物車中添加可口可樂 shopcar.add({id:1,name:"可口可樂",price:2.5,number:1}) // 首次向購物車中添加北京方便麪 shopcar.add({id:2,name:"北京方便麪",price:1,number:1}) //shopcar.remove(1); console.log(shopcar.car); let total = shopcar.jiezhang(); console.log("總額爲:",total); 14. 迭代器 用於遍歷的統一機制,這種機制容許咱們調用next()方法,每次調用都會返回一個對象 {value,done},當完成迭代後done值爲true,value每次獲取的元素 迭代器的使用 1) 手動使用 let iterator = array.values(); let item ; while(!(item = iterator.next()).done){ console.log(item.value); } 2) 使用for-of協助 let iterator = array.values(); for(let v of iterator){ console.log(v); } 3.使用for-of直接遍歷能夠迭代對象 for(let v of array){ console.log(v); } 誰具備迭代器? Array Set Map String 類數組對象 Arguments NodeList 4. 如何將一個普通對象變成一個能夠迭代的對象 let obj = {name:"terry",age:12} // 如何獲取一個迭代器 obj[Symbol.iterator] = [][Symbol.iterator] // 將對象轉換爲set new Set(obj) 15. entry [[key,val],[key,val],...] 16. 迭代器是如何添加到Set、Map、Array...這些數據結構上的? var o = { name:"terry", } o.iterator = iterator; o.iterator = "hello" Symbol() 這個函數能夠產生一個特殊符號,這個符號能夠用於key,經過這個key找見對應的函數。這個key好處在於它是隱式的。 17. Promise 構造函數,用於建立一個承諾對象,承諾對象主要用於封裝異步操做。 承諾發起 承諾成功 resolved 承諾失敗 rejected 1) 獲取或者建立一個承諾對象 let promise = new Promise(function(resolve,reject){ }) resolve 方法, 將承諾對象 pending -> resolved reject 方法, 將承諾對象 pending -> rejected 2) 使用承諾對象 Promise.prototype.then(successHandler[,errorHandler]) successHandler 當承諾成功的時候執行 errorHandler 當承諾失敗的時候執行 通常再也不then方法中添加errorHandler,而是將errorHandler放到catch中 返回值爲當前promise實例 Promise.prototype.catch(errorHandler) errorHandler 當承諾失敗的時候執行 Promise.prototype.finally(handler) handler 無論承諾對象的狀態變爲何樣子,這個handler函數都會執行 3) 高級特性 1. Promise.all([p1,p2,...]) 將多個承諾對象合併爲一個承諾對象,返回值爲promise promise .then((result)=>{ //當全部的承諾都resolved的時候該回調函數纔會執行 // result 爲每一個承諾對象返回值組成的一個數組 }) .catch(()=>{ //當有一個承諾對象rejected就會執行這個回調函數 }) 當查詢出全部顧客信息以及訂單信息後打開模態框 2. Promise.race([p1,p2,...]) 將多個承諾對象合併爲一個承諾對象,返回值爲promise promise .then((result)=>{ //只要有一個承諾對象的狀態變爲resolved,就會執行該回調函數 }) .catch(()=>{ //只要有一個承諾對象的狀態變爲rejected,就會執行該回調函數 }) 3. Promise.resolve(v) 將v轉換爲承諾對象 4. Promise.rejected(v) 返回一個狀態爲rejected的承諾對象 // 基於回調函數的封裝 get({url,success,error}){ let xhr = new XMLHttpRequest(); xhr.open("get",url); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.responseType = "json" xhr.send(); xhr.onreadystatechange = function(){ if(this.readyState === 4){ if(this.status === 200){ //請求成功 success(this.response) } else { //請求失敗 error(this) } } } } get({ url:"", success:function(){ }, error:function(){ } }) 18. Generator函數 Promise封裝了異步操做 $.get("/customer/findAll") .then((response)=>{ //經過回調函數來獲取異步操做的結果 }) 1) 聲明 function* foo(){ let a = "hello" yield a; yield "world"; return "end" } 2) 調用 let iterator = foo(); iterator.next() // {value:"hello",done:false} iterator.next() // {value:"world",done:false} iterator.next() // {value:"end",done:true} 3) this Generator與普通函數中的this的獲取是一致的 4) yeild表達式的返回值 默認是沒有返回值的 iterator.next(參數) 當前這個參數爲上一個yield表達式的返回值 5) 做用: 1. Generator函數能夠用於調用異步函數,將異步操做同步化 let customers = $.get("/customer/findAll"); let customerId = customers[0].id let address = $.get("/address/findByCustomerId?id="+Id) 2. 迭代器 將obj轉換爲可迭代器的對象 obj[Symbol.iterator] = ""[Symbol.iterator] Generator的返回值就是迭代器對象 let arr = [1,2,3]; arr.values() 迭代器對象 arr[Symbol.iterator] 生成迭代器對象的函數 課堂代碼: let obj = {"0":"terry","1":"larry","2":"tom"} obj[Symbol.iterator] = function* (){ //完成迭代obj的工做 for(let key in this){ let val = this[key]; yield [key,val]; } } 19. Async函數 是Generator函數的語法糖 async function foo(){ let customers = await $.get(url) let orders = await $.get(url) } let promise = foo() 1) await await表達式後通常爲promise,await會等待promise狀態改變resolved,而後將請求結果返回,最後繼續向下運行 經過id刪除顧客信息 function deleteById(id){ $.get(deleteById).then(()=>{ alert(""); $.get(findAll).then(()=>{ 從新渲染 }) }) } async版本 async function deleteById(id){ let result = await(deleteById,id); alert(result.message); await(findAll) } deleteById(1) 20. axios 基於promise機制的純粹的ajax框架 0) 特色 基於Promise 運行在nodejs、瀏覽器 自動轉換request,response data(默認將請求數據轉換爲json) Content-Type:"application/json" 攔截器 1) ajax解決方案 1) XMLHttpRequest 2) jQuery.ajax() 不涉及到數據驅動框架的時候使用 3) axios 涉及到數據驅動框架的時候 react/vue/angular + axios 在nodejs中能夠使用 2) 導入依賴 1) 瀏覽器 <script></script> 2) nodejs npm install axios --save 3) axios底層接口 axios({ url, method, data, // post請求的參數 params, // get請求的參數 baseURL, // 基礎路徑 responseType:'json', //要求服務器端返回值類型爲json transformRequest:[function(data,headers){ return data; }], //在請求發送到服務器前能夠改變data transformResponse:[function(data){ return data; }], //在響應數據到達then或者catch以前容許修改 headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type':"application/json" }, //異步操做 paramsSerializer: function (params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // get請求中,序列化params的函數,默認如上 timeout:0, //超時設置,默認不設置 withCredentials:false, // 設置是否攜帶瀏覽器cookie proxy:{ host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } }, //代理 xsrfXXX, // }) axios(config) 返回值爲promise對象 4) axios快捷接口 axios.get(url[,config]) axios.get(url+"?id="+id) axios.get(url,{params:{id}}) axios.post(url[,data][,config]) axios.post(url,{name:"terry"}) 5) Response Schema axios請求成功或者失敗後默認會將服務器端的返回結果封裝到一個新的對象,這個對象的數據結構: { data: {}, status: 200, statusText: 'OK', headers: {}, config: {}, request: {} } 6) 配置默認信息 axios有一個屬性defaults,在這個對象中配置的屬性全部的axios對象均可以應用到 axios.defaults.baseURL = "http://134.175.100.63:6677"}) axios.defaults.transformRequest = [] axios.defaults.transformResponse = [] axios.defaults.timeout = 10000; axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; axios.defaults.headers.common["Content-Type"] = "application/x-www-form-urlencoded"; axios.get("/customer/findAll") .then() axios.get("/order/findAll") .then() axiox.post(url,data) 默認狀況下data對象轉換爲json 7) 攔截器 與transformRequest,transformResponse功能相似,能夠在請求發送以前或者響應回來以後執行特定代碼。可是transformRequest,transformResponse主要用於對參數的格式化或者是對響應結果的格式化,而攔截器主要用於業務上面的攔截,主要能夠用於日誌的記錄,或者異常響應的統一處理... 1. 請求攔截器 axios.interceptors.request.use(function (config) { // 在請求發送以前能夠配置config // ... return config; }, function (error) { // 在請求出現異常的時候,默認返回失敗的承諾 return Promise.reject(error); }); 2. 響應攔截器 axios.interceptors.response.use(function (response) { // 通常在這裏能夠對響應結果進行處理 // response.data 纔是後臺返回的結果 return response; }, function (error) { // 提示異常信息 return Promise.reject(error); }); 21. 類 構造函數 = 類 類是構造函數的語法糖 1) es5構造函數 function Animal(name,age){ this.name = name; this.age = age; } Animal.prototype.sayName = function(){ console.log("my name is",this.name); } Animal.prototype.sayAge = function(){ console.log("my age is",this.age); } //繼承 function Dog(name,age,gender){ Animal.call(this,name,age) this.gender = gender; } Dog.prototype = new Animal(); Dog.prototype.constructor = Dog; Dog.prototype.sayGender = function(){ console.log("my gender is",this.gender); } let d = new Dog("一休",2,"male"); d.sayName() d.sayGender(); 2) 語法 1. 類的聲明 class 類名 { constructor(構造函數形式參數){ this.xxx = xxx; } xxx(){ } yyy(){ } } this表示當前構造函數的實例對象 2. 類的繼承 class 子類名 extends 父類名 { constuctor(子構造函數形式參數){ super(x,y) this.z = z; } } 任意一個類若是你不提供構造函數,那麼系統會爲你自動分配一個構造函數,這個構造函數以下 constructor(a,b,c){ super(a) } super 是借用構造函數的語法糖 3) this 無論是構造函數仍是普通方法,this都指向當前類的實例對象 22. ES6的模塊化 1) CommonJS模塊化 module.exports = 暴露接口 require(模塊名稱/路徑) 2) ES6模塊化 export 暴露的接口 import {} from "模塊名稱/路徑" 1. 定義模塊,經過export暴露接口 module1.js export let a = 3; export function sayHello(){ } index.js import {a,sayHello} from './module1' 2. 定義模塊,經過export default 暴露接口 module1.js let a = 3; function sayHello(){ } export default { a, sayHello } index.js import module1 from './module1' module1.sayHello 3. nodejs如何支持es6的模塊化 1) es6->es5 4. 案例: module1.js let name= "module1"; // 單獨暴露 export function sayName(){ console.log("my name is",this.name); } export function sayHello(){ console.log("hello world"); } index.js import {sayName} from './module1' 5. 案例 module1.js let name= "module1"; function sayAge(){}, function sayGender(){} // 默認集體暴露 export default { sayAge, sayGender } index.js import m from './module1' m.sayAge()