平時我們寫代碼時最高級的境界是自己寫的東西別人看不懂!哈哈哈!分享一些自己常用的js簡寫技巧,長期更新,會著重挑選一些實用的簡寫技巧,使自己的代碼更簡潔優雅~
這里只會收集一些大多數人不知道的用法,但是確實能提高自己的編碼技巧,像ES6那些基礎的簡寫語法或者是三目運算符代替if else那些我覺得是基礎,沒必要寫在這里浪費精力。
另外推薦一個只用一行代碼實現一個方法的實用網站
If-Else 用 || 或 ?? 運算符進行簡化
邏輯或操作符 ||,這里要注意的是 0 和 ‘’ 也會認為是false
如果 || 前面的值是 0 、false、null、 undefined 、NaN其中的任意一種,則直接返回||后面的值
function(obj){var a = obj || {}
}
// 等價于 =>>
function(obj){var a;if(obj === 0 || obj === "" || obj === false || obj === null || obj === undefined ||isNaN(obj)){a = {}} else {a = obj;}
}
空值合并操作符??如果沒有定義左側返回右側。如果是,則返回左側。
這種方法非常實用,有時候僅僅只是想判斷一個字段有沒有值,而不是把空字符串或者0也當做false處理
function(obj){var a = obj ?? {}
}
// 等價于 =>>
function(obj){var a;if(obj === null || obj === undefined){a = {}} else {a = obj;}
}
輸入框非空的判斷(有時候不想把0當成false可以用此方法。比如分數0也是個值,這種情況就不能認為是false)
if(value !== null && value !== undefined && value !== ''){}
// 等價于 ==>
if((value ?? '') !== ''){}
includes的正確使用姿勢
在上面邏輯或操作符||代碼段里有一個if判斷比較長,這時候就可以用includes去簡化代碼
if(obj === 0 || obj === "" || obj === false || obj === null || obj === undefined
){// ...
}// 使用includes簡化
if([0, '', false, null, undefined].includes(obj)){// ...
}
防止崩潰的可選鏈(?.)
可選鏈操作符?. 如果訪問未定義的屬性,則會產生錯誤。這就是可選鏈的用武之地。在未定義屬性時使用可選鏈運算符,undefined將返回而不是錯誤。這可以防止你的代碼崩潰。
const student = {name: "lwl",address: {state: "New York"},
}// 一層一層判斷
console.log(student && student.address && student.address.ZIPCode) // 輸出:undefined
// 使用可選鏈操作符
console.log(student?.address?.ZIPCode) // 輸出:undefined
可選鏈運算符也可以用于方法調用。如果方法存在,它將被調用,否則將返回 undefined。例如:
onst obj = {foo() {console.log('Hello from foo!')}
}obj.foo?.() // 輸出:'Hello from foo!'
obj.bar?.() // 輸出:undefined,因為 bar 方法不存在
同樣,數組也可以使用。例如:
const arr = [1, 2, 3, 4]console.log(arr[0]) // 輸出:1
console.log(arr[4]) // 輸出:undefined// 使用可選鏈運算符
console.log(arr?.[0]) // 輸出:1
console.log(arr?.[4]) // 輸出:undefined
console.log(arr?.[0]?.toString()) // 輸出:'1'
邏輯空賦值(??=)
邏輯空賦值??= 邏輯空賦值運算符(x ??= y)僅在 x 是 nullish (null 或 undefined) 時對其賦值。
const a = { duration: 50 };a.duration ??= 10;
console.log(a.duration);
// expected output: 50a.speed ??= 25;
console.log(a.speed);
// expected output: 25
快速生成1-10的數組
生成0-9,利用了數組的下標值
// 方法一
const arr1 = [...new Array(10).keys()]
// 方法二
const arr2 = Array.from(Array(10), (v, k) => k)
生成1-10,通過map的特性
const arr2 = [...Array(10)].map((v, i) => i + 1)
快速生成10個0的數組
const arr = new Array(10).fill(0)
快速生成10個[]的數組(二維數組)
二維數組不能直接寫成new Array(10).fill([])(也就是fill方法不能傳引用類型的值,[]換成new Array()也不行),因為fill里傳入引用類型值會導致每一個數組都指向同一個地址,改變一個數據的時候其他數據也會隨之改變,詳見 mdn官方說明
// 錯誤寫法
const arr = new Array(10).fill([]) // 注意這是錯誤寫法,不要這么寫
// 正確寫法
const arr = new Array(10).fill().map(() => new Array())
數組降維
你是否還在用遞歸給一個多維數組降維?如果是,那你應該知道一下es6的 flat()方法。
如果不確定需要降維的數組有多深,可以傳入最大值作為參數Infinity,默認值深度為1
const arr = [1, [2, [3, 4], 5], 6]
const flatArr = arr.flat(Infinity) // 輸出 [1, 2, 3, 4, 5, 6]
你是否在使用map的時候想要對數組降維?大概像這樣
const arr = [1, 2, 3, 4]
const result = arr.map(v => [v, v * 2]).flat()
console.log(result); // 輸出 [1, 2, 2, 4, 3, 6, 4, 8]
其實js也提供了更簡便的方法,那就是flatMap(),可以改成這樣:
const result = arr.flatMap(v => [v, v * 2])
從數組中刪除重復項
在 JavaScript 中,Set 是一個集合,它允許你僅存儲唯一值。這意味著刪除任何重復的值。
因此,要從數組中刪除重復項,你可以將其轉換為集合,然后再轉換回數組。
const numbers = [1, 1, 20, 3, 3, 3, 9, 9];
const uniqueNumbers = [...new Set(numbers)]; // -> [1, 20, 3, 9]
它是如何工作的?
new Set(numbers)從數字列表中創建一個集合。創建集合會自動刪除所有重復值。
展開運算符…將任何可迭代對象轉換為數組。這意味著將集合轉換回數組。[…new Set(numbers)]
在沒有第三個變量的情況下交換兩個變量
在 JavaScript 中,你可以使用解構從數組中拆分值。這可以應用于交換兩個變量而無需第三個
比較簡單,es6語法
let x = 1;
let y = 2;// 交換變量
[x, y] = [y, x];
將對象的值收集到數組中
用于Object.values()將對象的所有值收集到一個新數組中
const info = { name: "Matt", country: "Finland", age: 35 };// LONGER FORM
let data = [];
for (let key in info) {data.push(info[key]);
}// SHORTHAND
const data = Object.values(info);
指數運算符(用的不多)
你Math.pow()習慣把一個數字提高到一個冪嗎?你知道你也可以使用**運算符嗎?
雖然可以簡寫,不過我還是建議寫成Math.pow()方法,代碼更有語義化。
注意:**運算符要求操作數為數值類型,不過在js里也能正常運行。
Math.pow(2, 3); // 輸出: 8
2 ** 3; // 輸出: 8 Math.pow(4, 0.5); // 輸出: 2
4 ** 0.5; // 輸出: 2 Math.pow(3, -2); // 輸出: 0.1111111111111111
3 ** -2; // 輸出: 0.1111111111111111 Math.pow('2', '3'); // 輸出: 8 (參數被自動轉換為數字)
'2' ** '3'; // js中輸出: 8,其他語言可能報錯
Math.floor() 簡寫(用的不多)
向下取整Math.floor()并不是什么新鮮事。但是你知道你也可以使用~~運算符嗎?
同上雖然可以簡寫,不過我還是建議寫成Math.floor()方法,代碼更有語義化。
注意:對于正數而言兩者都是直接去掉小數位,但對于負數來說Math.floor()是向下取整,~~依然是只去掉小數位,整數位不變。 請看下面輸出結果:
Math.floor(3.14); // 輸出: 3
Math.floor(5.7); // 輸出: 5
Math.floor(-2.5); // 輸出: -3
Math.floor(10); // 輸出: 10~~3.14; // 輸出: 3
~~5.7; // 輸出: 5
~~(-2.5); // 輸出: -2
~~10; // 輸出: 10
逗號運算符(,)
逗號( , )運算符對它的每個操作數從左到右求值,并返回最后一個操作數的值。這讓你可以創建一個復合表達式,其中多個表達式被評估,復合表達式的最終值是其成員表達式中最右邊的值。這通常用于為 for 循環提供多個參數。
這里只說一下函數return的時候用逗號運算符簡化代碼的技巧,其他用法請直接點擊查看官方文檔。
舉一個簡單的例子:
// 簡化前
const result = arr => {arr.push('a')return arr
}
console.log(result([1,2])) // 輸出:[1, 2, 'a']
這段代碼需要返回修改后的數組,不能直接return arr.push(‘a’),因為push的返回值是修改后數組的長度,這時候可以用逗號運算符簡化成一行代碼。
// 簡化后
const result = arr => (arr.push('a'), arr)
console.log(result([1,2])) // 輸出:[1, 2, 'a']
Array.map()的簡寫
比如想要拿到接口返回的特定字段的值,可以用解構賦值和對象的簡寫方法對map方法簡寫。
比如接口返回數據,此時如果只想要數據里的id和name,就可以用下面的簡寫方式。
// 接口返回數據
res = [{id: 1,name: 'zhangsan',age: 16,gender: 0
}, {id: 2,name: 'lisi',age: 20,gender: 1
}]// 第一種方法:箭頭函數、 解構賦值
const data = res.map(({id, name}) => ({id, name}))
// 第二種方法:箭頭函數、返回對象(相對更容易理解)