首页 前端开发编码习惯
文章
取消

前端开发编码习惯

前言

好的编码习惯,能够提升个人技术素养,产品质量,减少bug数量,易维护,易迭代,多人协作易沟通交接等多个好处。今天从个人角度谈谈自己的一些编码习惯,以及为什么要这么做。

这并不是什么技术标准,不同的人有不同的看法和喜好。 但我们要牢记一条:优秀的代码一定是可读性非常高的代码。

基础篇

主要从javascript代码的基础编写的角度阐述。

=====

在遇到基本数据类型判断的情况下,强制使用全等于判断===。因为js是是弱类型语言,非全等判断==会存在隐式类型转换的问题,在一个复杂的业务场景中,如果导出充斥着非全等判断,那么开发者可能会无法第一时间明确业务中过的数据类型及结构,对后来的协作开发人员也非常不友好。而在其他大部分编程语言中,包括近年火热的Typescript本身也是有解决这一问题。 所以在我们开发中遇到当前场景,务必使用全等判断,如果数据类型不明确,我们也要通过其他方法转换成明确的类型再继续判断。

1
2
3
4
let a = '0'
console.log(a == false)
console.log(Number(a) == false)
console.log(Number(a) === false)

数据类型转换

数据类型转换分为强制转换和隐形转换。在大多数场景建议使用强制转换。转换字符串使用String,数字使用Number, 因为隐式转换的写法具有一定的迷惑性,大量的隐式转换放在一起会大大降低代码的可读性,某些场景下会使代码变得不稳定,增加bug排查难度,所以尽量避免书写隐式转换类型的代码。

1
2
console.log(+'1' + '1' + +'1' )
console.log(+'1' + +'1' +'1')

不要使用过时的Javscript技巧

了解ES高版本语法,如果可以,尽可能面使用新语法开发,因为高阶语法在底层实现上性能通常会优于旧版本。 一个经典的例子是搜索一个数组是否包含一个元素。 使用 array.indexOf(item) !== -1来监测元素是否存在。 ECMAScript 2015及更高版本的功能变得越来越强大。 你可以使用新的语言特性安全地重构很多hacks。 使用ES2015方法 array.includes(item)重构array.indexOf(item) !== -1

1
2
3
4
5
6
7
8
const arr = [1,2,3,4,5,6,7,8,9]
// 查找数组arr中是否有 number 5
console.log(arr.indexOf(5) !== -1) // bad
console.log(arr.includes(5)) //good

// 查找数组中所有大于数字6的元素
// 判断数组中所有的元素是否大于数字3
// 数组中所有元素的累加和是多少

不要污染函数作用域

在ES6之前,通常会在顶级作用域或函数作用域顶级声明所有变量,但其实一些变量只在某一块作用域生效,所以会造成作用域污染,所以我们要尽可能的控制每一个变量的生命周期。比如ES6开始引入的块级作用域的概念,可以很方便的解决这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
// 错误的
let message;
if (notFound) {
  message = 'xxxxxx'
  // 使用 message...
}

// 正确的
if (notFound) {
  const message = 'xxxxxx'
  // 使用 message...
}

避免使用null作为函数入参

避免使函数的入参为null, 一旦null出现在调用堆栈中,就需要在每一个可能访问的函数检查中,来判断是否为null

函数导出

全局公共函数导出文件,不推荐export一个对象的方式,而是export一个个函数的形式。这样可以实现按需导入.

1
2
3
4
5
6
7
8
9
10
// bad
util.fun = function() {};
export default util;
// bad
export default {
	fun
}
// good
export function fun() {};
import {fun} from '';

了解高阶函数,在正确场景使用正确的函数

1
2
3
4
5
6
// 如果只是遍历
const arr = [1, 2, 3];
// bad 
arr.map(item => {});
// good
arr.forEach(item => {});

如果数据量特别大,尤其是遍历操作,推荐使用普通for循环,因为高阶函数的底层也是封装的for循环

1
2
3
const arr = [];
// beat
for (let i = 0, len = arr.length; i < len; i++) {}

链式调用使用 缩进和.强调调用而非新语句

1
2
3
4
5
6
7
8
9
// bad
 $('#items').find('.selected').highlight().end().find('.open').updateCount()
// good
 $('#items')
   .find('.selected')
   .highlight()
   .end()
   .find('.open')
   .updateCount()

删除无用的大篇幅代码注释

涂鸦墙

删除没有必要的声明

1
2
3
4
5
6
7
8
9
10
11
12
13
// bad
let dataList = []
dataList.push(row)
let data = {
  code: this.code,
  list: dataList
}

// good
let data = {
  code: this.code,
  list: [ row ]
}

事件处理

注重隔离应用逻辑和用户行为,专注一个函数只做一件事,便于函数复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// bad
function handClick (event) {
  const popup = document.getElementById("popup")
  popup.style.left = event.clientX
  popup.style.top = event.clientY
  popup.className = "show"
}

// good
function showPopup(event){
  const popup = document.getElementById("popup")
  popup.style.left = event.clientX
  popup.style.top = event.clientY
  popup.className = "show"
}
function handClick (event) {
  showPopup(event)
}

适当抛出自定义错误

当业务变得复杂,需求变得庞大,适当的抛出自定义错误, 有助于调试,及加深业务理解。

1
throw new Error('函数名:可能得原因')

不要使用随意的编码风格(不要破坏项目的编码风格)

开始一个新项目首先要确定整体代码风格,可以参考已有的代码风格,配合eslint配置验证。接手一个项目,在开始编码前,确认当前项目的代码风格并严格遵守。 有什么比阅读具有随机编码风格的代码更令人生畏的呢? 你永远不知道会发生什么! 如果代码库包含许多开发人员的不同编码风格怎么办? 各式各样的人物涂鸦墙。

涂鸦墙

组件封装要确保组件代码可读性

公共组件是团队协作的基础,可读性就显得尤为总要,怎么增加组件的可读性呢?首先组件命名要语义化,大家看到组件就一目了然,知道该组件的功能是啥;其次我们组件要有一个清晰明了的注释,演示组件用例,属性、参数、方法说明,让大家几乎不用动脑就可以完美使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 表格筛选器组件
 *
 * 使用说明:
 * 1,导入组件:import TableFilter from "~/components/sizer/TableFilter.vue"
 * 2,注册组件:components: {TableFilter}
 * 3,渲染:<TableFilter :listSizer="listSizer" :listPrmt="listPrmt" @ichub="search"></TableFilter>
 *
 * 属性说明:
 * :listSizer:Array 过滤器基本配置项
 * :listPrmt:Object 过滤参数对象
 * @ichub: function 点击ichub按钮过滤事件--参数:Object 当前过滤参数对象
 *
 * 数据说明:
 * listSizer: [{  /过滤器基本配置项数据
 *      type: "text", //输入框类型:text普通输入框,select下拉输入框,date时间选择输入框
 *      placeholder: "型号", //输入框提示
 *      name: "sku_name", //绑定的字段名与listPrmt里面的键对应
 *      key: "f_sku_name", //循环唯一标识key
 *      width: "g-width-15" //输入框站筛选器的宽度(百分比)
 *  }]
 ** /
组件要注重逻辑功能和理性

封装公共组件要设计好组件功能,看哪些功能需要在组件内完成,哪些功能需要暴露给父组件。我们一般的设计原则是,能在组件内完成的功能,尽量不要暴露给父组件处理。

组件数据设计注重合理性

哪些数据需要父组件传进组件,哪些数据是组件自身拥有,哪些数据要输出给父组件一定要条理清晰。设计原则:组件自身除了必要的数据,一般不携带大量私有数据,尽量由父组件输入,处理完后根据业务场景决定是否需要输出。

组件注重扩展性

我们封装公共组件基本可以满足我们百分之80到90的业务场景,但是一些个性化话的场景,需要组件的大部分功能,但是又有新的需求,这时候再开发一个新的组件没有必要,那么我们就要在原有组件的基础上加功能。这是时候我们就要用到插槽slot来做好预留,来增强组件的扩展性。

代码文件适当拆分

  • 代码篇幅过大时,解偶归类部分方法,迁移到另一个文件,再import进来使用
  • 定义顶级常量数据, 可考虑迁移到单独的文件中管理。
本文由作者按照 CC BY 4.0 进行授权