吖蛋

V1

2023/01/06阅读:89主题:默认主题

JavaScript代码简洁之道

JavaScript代码简洁之道

1.通过条件判断给变量赋值布尔值的正确姿势

// bad
if (a === 'a') {
 b = true
else {
 b = false
}

// good
b = a === 'a'

2.在if中判断数组长度不为零的正确姿势

// bad
if (arr.length !== 0) {
  // ...
}

// good
if (arr.length) {
  // ...
}

3.同理,在if中判断数组长度为零的正确姿势

// bad
if (arr.length === 0) {
  // ...
}

// good
if (!arr.length) {
  // ...
}

4.简单的if判断使用三元表达式

// bad
if (a === 'a') {
  b = a
else {
  b = c
}

// good
b = a === 'a' ? a : c

5.使用includes简化if判断

// bad
if (a === 1 || a === 2 || a === 3 || a === 4) {
  // ...
}

// good
let arr = [1234]
if (arr.includes(a)) {
  // ...
}

6.使用some方法判断是否有满足条件的元素或every检测所有元素都满足指定条件

// bad
let arr = [1357]
function isHasNum (n{
  for (let i = 0; i < arr.length; i ++) {
    if (arr[i] === n) {
      return true
    }
  }
  return false
}

// good
let arr = [1357]
let isHasNum = n => arr.some(num => num === n)

// best
let arr = [1357]
let isHasNum = (n, arr) => arr.some(num => num === n)

7.使用forEach方法遍历数组,不形成新数组

// bad
for (let i = 0; i < arr.length; i ++) {
  // ...
  arr[i].key = balabala
}

// good
arr.forEach(item => {
  // ...
  item.key = balabala
})

8.使用filter方法过滤原数组,形成新数组

// bad
let arr = [1357],
  newArr = []
for (let i = 0; i < arr.length; i ++) {
  if (arr[i] > 4) {
    newArr.push(arr[i])
  }
}

// good
let arr = [1357]
let newArr = arr.filter(n => n > 4// [5, 7]

9.使用map对数组中所有元素批量处理,形成新数组

// bad
let arr = [1357]
let newArr = []
for (let i = 0; i < arr.length; i ++) {
  newArr.push(arr[i] + 1)
}

// good
let arr = [1357]
let newArr = arr.map(n => n + 1// [2, 4, 6, 8]

10.巧用对象(数组)方法,避免使用for...in(for循环),使用Object.values快速获取对象键名

let obj = {
  a1,
  b2,
}
// bad
let values = []
for (key in obj) {
  values.push(obj[key])
}

// good
let values = Object.values(obj) // [1, 2]

11.使用Object.keys快速获取对象键名

let obj = {
  a1,
  b2,
}
// bad
let keys = []
for (value in obj) {
  keys.push(value)
}

// good
let keys = Object.keys(obj) // ['a', 'b']

12.解构数组进行变量值的替换

// bad
let a = 1
let b = 2
let temp = a
a = b
b = temp

// good
let a = 1
let b = 2
[b, a] = [a, b]

13.解构对象赋值

// bad
function getFullName (user{
  const firstName = user.firstName
  const lastName = user.lastName
  return `${firstName} ${lastName}`
}

// good
function getFullName (user{
  const { firstName, lastName } = user
  return `${firstName} ${lastName}`
}

// better
function getFullName ({ firstName, lastName }{
  return `${firstName} ${lastName}`
}

14.解构时重命名简化命名(针对后端返回字段命名过长)

// bad
setForm (data) {
  this.one = data.aaa_bbb_ccc_ddd
  this.two = data.eee_fff_ggg
}

// good
setForm ({aaa_bbb_ccc_ddd, eee_fff_ggg}) {
  this.one = aaa_bbb_ccc_ddd
  this.two = eee_fff_ggg
}

// best
setForm ({aaa_bbb_ccc_ddd: one, eee_fff_ggg: two}) {
  this.one = one
  this.two = two
}

15.解构时设置默认值

// 针对非接口,处理逻辑功能函数建议按需要设置默认值,入参需要
// bad 功能函数不需要接口,入参就能给与默认值
function setForm ({name, age}{
  if (!age) age = 16 // age = age || 16  
  this.name = name
  this.age = age
}

// good
function setForm ({name, age = 16}{
  this.name = name
  this.age = age
}

// 针对接口的赋值推荐可不设置解构默认值
const getData = async ({id}) => {
  const {local, warehouseList} = await apiXXXXX({id});
  
  // 当参数需要默认值再做一次处理
  warehouseList = warehouseList || []; 
}

16.||短路符设置默认值

let person = {
  name'张三',
  age38,
}

// bad
let name
if (!person.name) {
  person.name = '佚名'
}
name = person.name

// good
let name = person.name || '佚名'

17.&& 用 ? 替代, 防止报错

// bad
let childrenName = person.children && person.childre.name

// good
let childrenName = person.childre?.name

18.字符串拼接使用模板字面量 ${}

let person = {
  name'LiMing',
  age18,
}

// bad
function sayHi (obj{
  console.log('大家好,我叫' + person.name = ',我今年' + person.age + '了')
}

// good
function sayHi (person{
  console.log(`大家好,我叫${person.name},我今年${person.age}了`)
}

// best
function sayHi ({name, age}{
  console.log(`大家好,我叫${name},我今年${age}了`)
}

19.无说明的参数

// bad
if (value.length < 8) { // 为什么要小于8,8表示啥?长度,还是位移,还是高度?
 ...
}

// good
const MAX_INPUT_LENGTH = 8;
if (value.length < MAX_INPUT_LENGTH) { // 一目了然,不能超过最大输入长度
 ...
}

20.命名过于啰嗦

// bad
let nameString;
let theUsers;

// good
let name;
let users;

21.长代码不知道啥意思,无说明

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
  address.match(cityZipCodeRegex)[1], //长代码不知道这个代表什么
  address.match(cityZipCodeRegex)[2], //长代码不知道这个代表什么
);

// good
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

22.函数传参,传参无说明

// bad
page.getSVG(api, truefalse); // true和false啥意思,一目不了然

// good
page.getSVG({
 imageApi: api,
 includePageBackgroundtrue// 一目了然,知道这些true和false是啥意思
 compressfalse,
})

23.先使用函数式编程,尽量不使用for循环编程

// bad
for(i = 1; i <= 10; i++) {
   a[i] = a[i] +1;
}

// good
let b = a.map(item => ++item)

24.函数中过多的采用if else .. if else.. 过多

// bad
if (a === 1) {
 ...
else if (a ===2) {
 ...
else if (a === 3) {
 ...
else {
  ...
}
  
// good  看需要是否更换为策略模式
switch(a) {
   case 1:
        ....
   case 2:
     ....
   case 3:
     ....
  default:
    ....


// good
if (a === 1) { // 大概率的往上提
  ...
  return;
}
  
if (a === 2) {
  ...
  return;
}
  
if (a === 3) {
  ...
  return;
}
...

25.在编程中少用else

// bad
if (subject === 'Mockingbird') {
  return author === 'Harper Lee'
else {
  return author === 'Nue'
}

// good
if (subject === 'Mockingbird') {
  return author === 'Harper Lee'
}
return author === 'Nue'

26.减少副作用,尽可能使用没有副作用的纯函数

// bad
function addItemToCart (cart, item, quantity = 1{
  const alreadyInCart = cart.get(item.id) || 0
  cart.set(item.id, alreadyInCart + quantity)
  return cart
}

// good
function addItemToCart (cart, item, quantity = 1{
  const cartCopy = new Map(cart)
  const alreadyInCart = cartCopy.get(item.id) || 0
  cartCopy.set(item.id, alreadyInCart + quantity)
  return cartCopy
}

27.减少使用链式赋值

// bad
var a = b = c = 1

// good
var a = 1
var b = 1
var c = 1

28.变量声明

// bad
var a, b, c

// good
var a
var b
var c

29.使用字面量值创建对象或数组

// bad
const a = new Object{}

// good
const a = {}

// bad
const items = new Array()

// good
const items = []

30.请使用对象属性值的简写方式

// bad
const item = {
  job: job
}

// good
const item = {
  job
}

31.对象属性值的简写方式要和声明式的方式分组

const job = 'FrontEnd'
const department = 'JDC'

// bad
const item = {
  sex'male',
  job,
  age25,
  department
}

// good
const item = {
  job,
  department,
  sex'male',
  age25
}

32.使用拓展运算符 ... 复制数组,浅拷贝不满足时,使用lodash的深拷贝

const items = []
const itemsCopy = []

// bad
const len = items.length
let i
for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i]
}

// good
itemsCopy = [...items]

33.函数需要回传多个值时,请使用对象的解构,而不是数组的解构

// bad
function doSomething ({
  return [top, right, bottom, left]
}
// 需要考虑数据的顺序
const [top, xx, xxx, left] = doSomething()

// good
function doSomething ({
  return { top, right, bottom, left }
}
// 此时不需要考虑数据的顺序
const { top, left } = doSomething()

34.优先使用.来访问对象属性,不满足再使用[]

const joke = {
  name'haha',
  age28
}

// bad
const name = joke['name']

// good
const name = joke.name

35.先考虑Map(映射)是否满足,不满足再考虑使用数组

// 不推荐
const SellingTypeList = [
  { label'common Carton'value1 },
  { label'common Pcs'value2 },
  { label'common Pack'value3 },
];

// 推荐
const SellingType = {
  CommonCarton1,
  CommonPcs2,
  CommonPack3,
}

// 当有需要时再写
const SellingTypeStr = {
  [SellingType.CommonCarton]: 'common Carton',
  [SellingType.CommonPcs]: 'common Pcs',
  [SellingType.CommonPack]: 'common Pack',
}

// better
enum SellingType {
  CommonCarton = 1,
  CommonPcs = 2,
  CommonPack = 3,
}

const SellingTypeStr = {
  [SellingType.CommonCarton]: 'common Carton',
  [SellingType.CommonPcs]: 'common Pcs',
  [SellingType.CommonPack]: 'common Pack',
}

36.delete超过2个以上使用lodash的omit或者解构赋值

var object = {
  'a'1,
  'b''2',
  'c'3,
  'd'4,
  ...
};

// bad
delete object.a
delete object.c
delete object.d

// good
_.omit(object, ['a''c''d']);

// OR
const { a, c, d, ...newObject } = object;

分类:

前端

标签:

JavaScript

作者介绍

吖蛋
V1