JavaScript闖關筆記
介紹
通過Array/Object/Function基礎型別編寫。
看到自己不瞭解的或者比較新穎的用法便會寫上。
不定時更新內容。
本文首發於我的個人網站:Timbok.top
目錄
-
Array
-
Object
-
Function
Array
迭代方法
- every()方法對陣列中的每一項執行給定函式,如果該函式對每一項都返回 true,則返回 true
const arr = [1,2,3,4]; const result = arr.every((item, index, arr)=>{ return item > 2; }); console.log(result); // false
- some()方法 對陣列中的每一項執行給定函式,如果該函式對任一項返回 true,則返回 true
const arr = [1, 2, 3, 4]; const result = arr.some((item, index, arr)=>{ return item > 2; }); console.log(result); // true
- filter()方法對陣列中的每一項執行給定函式,返回該函式會返回 true 的項組成的陣列
const arr = [1, 2, 3, 4]; const result = arr.filter((item, index)=>{ return item > 2; }); console.log(result); // [3, 4]
- map()方法 對陣列中的每一項執行給定函式,返回每次函式呼叫的結果組成的陣列
const arr = [1, 2, 3, 4]; const result = arr.map((item, index)=>{ return item * index; }); console.log(result); // [0, 2, 6, 12]
- forEach()方法 對陣列中的每一項執行給定函式。這個方法沒有返回值,本質上與使用 for 迴圈迭代陣列一樣
const arr = [1, 2, 3, 4]; const result = arr.forEach((item, index)=>{ // 執行某些操作 });
- reduce() 方法 接收一個函式作為累加器,陣列中的每個值(從左到右)開始縮減,最終計算為一個值。對空陣列是不會執行回撥函式的。
arr.reduce(callback,[initialValue])
-
callback (執行陣列中每個值的函式,包含四個引數)
- previousValue (上一次呼叫回撥返回的值,或者是提供的初始值(initialValue))
- currentValue (陣列中當前被處理的元素)
- index (當前元素在陣列中的索引)
- array (呼叫 reduce 的陣列)
- initialValue (作為第一次呼叫 callback 的第一個引數。)
無返回值
const arr = [1, 2, 3]; arr.reduce((pev, item)=>{ console.log(pev, item); }, 0); // 執行結果依次為:0 1; undefined 2; undefined 3;
有返回值
// pev為上次迭代return的值 const arr = [1, 2, 3, 4]; const result = arr.reduce((pev, item)=>{ console.log(pev); return pev + item; }, 0); console.log(result); // 10 // pev執行結果依次為:0, 1, 3, 6
split和join
split(): 用於把一個字串分割成字串陣列。
const string = '1, 2, 3, 4, 5'; string.split(','); // ["1", "2", "3", "4", "5"]
如果string為空,則返回一個空陣列
const string = ''; string.split(','); // [""] string.split(); // [""]
join(): 用於把陣列中的所有元素放入一個字串。
const array = [1, 2, 3, 4, 5]; array.join(); // '1,2,3,4,5' 預設用,分割 array.join('|'); // "1|2|3|4|5" 預設用,分割
Object
object對映
定義一個object作為配置物件來存放不同狀態,通過連結串列查詢
const statusMap = { 1:()=>{ console.log('a1') }, 2:()=>{ console.log('b2') } /* n.... */ } // 執行 let a = 1 statusMap[a]() // a1
這樣比較清晰,將條件配置與具體執行分離。如果要增加其他狀態,只修改配置物件即可。
Function
promise
ECMAscript 6 原生提供了 Promise 物件。
Promise 物件代表了未來將要發生的事件,用來傳遞非同步操作的訊息。
Promise 物件有以下兩個特點:
1、物件的狀態不受外界影響。Promise 物件代表一個非同步操作,有三種狀態:
- pending: 初始狀態,不是成功或失敗狀態。
- fulfilled: 意味著操作成功完成。
- rejected: 意味著操作失敗。
只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是 Promise 這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。
2、一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise 物件的狀態改變,只有兩種可能:從 Pending 變為 Resolved 和從 Pending 變為 Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對 Promise 物件添加回調函式,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。
簡單實現:
function _promise(params) { return new Promise((resolve, reject)=>{ params>0 ? resolve('正數') : reject('負數'); }); } _promise(1).then(res=>console.log(res)) // 正數 _promise(-1).catch(res=>console.log(res)) // 負數
Promise.all
Promise.all
可以將多個Promise例項包裝成一個新的Promise例項。同時,成功和失敗的返回值是不同的,成功的時候返回的是一個結果陣列,而失敗的時候則返回最先被reject失敗狀態的值。
let p1 = new Promise((resolve, reject) => { resolve('成功了') }) let p2 = new Promise((resolve, reject) => { resolve('success') }) let p3 = Promise.reject('失敗') Promise.all([p1, p2]).then((result) => { console.log(result)//['成功了', 'success'] }).catch((error) => { console.log(error) }) Promise.all([p1,p3,p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error)// '失敗' })
需要特別注意的是,Promise.all獲得的成功結果的數組裡面的資料順序和Promise.all接收到的陣列順序是一致的,即p1的結果在前,即便p1的結果獲取的比p2要晚。這帶來了一個絕大的好處:在前端開發請求資料的過程中,偶爾會遇到傳送多個請求並根據請求順序獲取和使用資料的場景,使用Promise.all毫無疑問可以解決這個問題。
Promise.race
顧名思義,Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])裡面哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態。
let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('success') },1000) }) let p2 = new Promise((resolve, reject) => { setTimeout(() => { reject('failed') }, 500) }) Promise.race([p1, p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error)// 開啟的是 'failed' })
async-await
ES2017 標準引入了async
函式,使得非同步操作變得更加方便。
async
函式是什麼?一句話,它其實就是promise
和Generator
函式的語法糖。
async
async
用來表示函式是非同步的,定義的函式會返回一個promise物件,可以使用then方法添加回調函式。
async function test() { return 123; } test().then(res => { console.log(res);// 123 }); 若 async 定義的函式有返回值,return 123;相當於Promise.resolve(123),沒有宣告式的 return則相當於執行了Promise.resolve();
await
await
可以理解為是 async wait 的簡寫。await 必須出現在 async 函式內部,不能單獨使用。
function notAsyncFunc() { await Math.random(); } notAsyncFunc();//Uncaught SyntaxError: Unexpected identifier
await
後面可以跟任何的JS 表示式。雖然說await
可以等很多型別的東西,但是它最主要的意圖是用來等待Promise
物件的狀態被resolved
。如果await的
是promise
物件會造成非同步函式停止執行並且等待promise
的解決,如果等的是正常的表示式則立即執行。
function sleep(second) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(' enough sleep~'); }, second); }) } function normalFunc() { console.log('normalFunc'); } async function awaitDemo() { await normalFunc(); console.log('something, ~~'); let result = await sleep(2000); console.log(result);// 兩秒之後會被打印出來 } awaitDemo(); // normalFunc // VM4036:13 something, ~~ // VM4036:15enough sleep~
希望通過上面的 demo,大家可以理解我上面的話。
錯誤處理
上述的程式碼好像給的都是resolve的情況,那麼reject的時候我們該如何處理呢?
function sleep(second) { return new Promise((resolve, reject) => { setTimeout(() => { reject('want to sleep~'); }, second); }) } async function errorDemo() { let result = await sleep(1000); console.log(result); } errorDemo();// VM706:11 Uncaught (in promise) want to sleep~ // 為了處理Promise.reject 的情況我們應該將程式碼塊用 try catch 包裹一下 async function errorDemoSuper() { try { let result = await sleep(1000); console.log(result); } catch (err) { console.log(err); } } errorDemoSuper();// want to sleep~ // 有了 try catch 之後我們就能夠拿到 Promise.reject 回來的資料了。
最後一點,await必須在async函式的上下文中的。