写JS一定要优雅!
0. 写在前头
这篇文章会不时更新补充,记录我自己平时在学习以及实际开发过程中,总结整理的一些关于JS的优雅写法
鄙人是一个重度代码洁癖患者
,能一行代码解决的事,绝对不会书写多行,能代码上下平铺,绝对不会if-if-if
多层嵌套
当然了,鄙人码龄不过3年,水平有限,但又喜欢写一些博客记录,属于又菜又爱玩的类型。如有写得不好,写得不对的地方,欢迎各位大佬批评指正!
那么不多bb,进入正题~
1. 使用一些位运算取代丑陋的Math方法
1.1 取中间值 >>1
针对于正数才有效
let arr = [1,2,3,4,5,6,7]
let l = 0, r = arr.length - 1
// let m = Math.floor((l+r)/2)
let m = l + r >> 1
1.2 向下取整 | 0
function getDigit(n){
let digits = []
while(n){
digits.push(n % 10)
// n = Math.floor(n / 10)
n = (n / 10) | 0
}
}
1.3 判断奇偶 & 1
let n = 9
if(n % 2 == 0) {
// 偶...
} else {
// 奇...
}
// 改进
if( n & 1 ) { ... }// 奇
else { ... } // 偶
2.用一行代码取代多行代码
2.1 用三目代替if-else
// 是可以,但是不够省键盘
if(n > 0) {
fn1()
} else {
fn2()
}
// 改进
n > 0 ? fn1() : fn2()
// 是可以,但是不够优雅
let n
if (m > 0) {
n = 1
} else {
n = 3
}
// 改进
let n = m > 0 ? 1 : 3
// 逻辑可以,但阅读和书写都不太可以,必须要优雅
async function saveForm() {
if (isCreate) { // 创建
let params = {
user: "noxone",
age: 17,
isHandsome: true
}
let res = await apiCreateUser(params)
if (res.code == "0") alert("创建成功")
else alert(res.message)
} else { // 编辑
let params = {
id: 295286392
user: "noxone",
age: 17,
isHandsome: true
}
let res = await apiEditUser(params)
if (res.code == "0") alert("编辑成功")
else alert(res.message)
}
}
// 改进
async function saveForm(isCreate) {
let params = {
user: "noxone",
age: 17,
isHandsome: true
}
let { code, message } = isCreate ?
await apiCreateUser(params)
: await apiEditUser({id: 295286392, ...params})
if (code !== "0") alert(message)
else alert(isCreate ? "创建成功" : "编辑成功")
}
2.2 用与逻辑代替if-fn()
if (n > 2) {
fn()
}
// 省字高效
n > 2 && fn()
2.3 用for代替while
function reverse(arr) {
let l = 0, r = arr.length - 1
while (l < r) {
[arr[l++], arr[r--]] = [arr[r], arr[l]]
}
}
// for
function reverse(arr) {
for (let l = 0, r = arr.length - 1; l < r;){
[arr[l++], arr[r--]] = [arr[r], arr[l]]
}
}
2.4 利用好布尔值
// 以下代码看着费劲
function fn(n) {
let flag
if (n > 5) {
flag = true
} else if(n % 2 == 0) { // 偶数
flag = true
} else {
flag = false
}
return flag
}
// 改进
function fn(n) {
return n > 5 || n % 2 == 0
}
// 以下代码看着也费劲
function fn(num, str, obj, arr) {
if (num == 0) {
return false
}
if (str == '') {
return false
}
if (obj == null) {
return false
}
if (arr.length == 0) {
return false
}
if (arr.indexOf(1) != -1 || arr.indexOf(2) != -1 || arr.indexOf(3) != -1) {
return false
}
return true
}
// 改进:利用好js的假值及自动类型转换特性
function fn(num, str, obj, arr) {
return !!n && !!str && !!obj && !!arr.length && arr.some(n=>[1,2,3].includes(n))
}
同上
var n = 5
if (n != 0) {
// ...
} else {
// ...
}
// 改成这样
var n = 5
if (n) {
// ...
} else {
// ...
}
// 同理
var arr = []
var str = 'abc'
var obj = null
if (!arr.length) {
// 空数组
} else {
// 非空
}
if (!str) {
// 空字符串
}
if (obj) {
// 非null
} else {
// null
}
3. 不要if-if-if多层套娃
以下代码是4层if-else嵌套的代码,即使已经将具体逻辑封装到一个个函数里边了,但是还是看着费劲,更别说未封装的情况!
理论上大于3层的代码都不好理解,且维护困难,容易出问题!
// holy shit!!!
function fn(data) {
if (data !== null) {
if (data.num >= 5) {
fn2()
if (data.flag) { // 是否可以data.flag && data.isAdmi呢?
if(data.isAdmin) {
fn3()
}
} else{
fn3Err()
}
} else if (data.num >= 0) {
fnErr2()
} else {
fnErr3()
}
} else {
fnErr()
}
}
这时候需要把横向嵌套的层数降低,代码书写方式尽量是自上而下
,而非上左右下
改进方法:先处理坏情况
,剩下的就是好情况
,从而把横向嵌套层数降为0,实现自上而下
function fn(data) {
if (data == null) return fnErr() // 1级坏情况:data为null
if (data.num < 0) return fnErr2() // 2级坏情况
if (data.num < 5) return fnErr3() // 2级坏情况
// 剩下的就是1级好情况了,即data !== null && data.num >= 5
fn2()
if (!data.flag || data.isAdmin) return fn3Err() // 3级坏情况
fn3()
// 或 data.flag ? fn3() : fn3Err()
}
是不是豁然开朗多了?
转载自:https://juejin.cn/post/7235137314400862268