关于重构问题——编写可维护性高的代码

1、使用TypeScript:html

背景:前端

RollBar是一个网页检测的网站,该网站统计了2018年前端项目抛出异常的种类,其中有七种是type error,即类型错误。异常最多的类型是读取了undefined变量的属性node

而这个问题能够经过TS定义严格的数据类型解决:webpack

type TypeApple = { name: string, count: number }
/** @type {TypeApple} */ const apple = { name: 'foo', count: 100 }

TS和VSCode(一款IDE)结合,也能够实现静态类型检测,只不过使用注释形式,同样支持tsconfig.json和自定义Typing。git

如何使用TS:github

npm install –g typescript
tsc –v

1.新建 .ts 后缀的文件 —— 2.编写知足 ts 风格的代码——3.使用tsc编译ts文件(最后获得的仍是js文件)web

TS主要语法:typescript

1.类型系统:npm

2.接口编程

 在TypeScript中,接口的做用是对值所拥有的结构进行类型检查,接口是一种结构约束。同时提供了一种方式去抽象代码。

3.类

js自己并非一种OOP(面向对象编程)的语言,并无类这样一个概念。JS的对象使用原型链进行继承和扩展。ES6中提供的Class关键字只是一个语法糖,让你用面向对象的方式编写类,底层仍是原型链的连接。

继承,以某个类为父类,继承全部的属性和方法,同时能够进行扩展和重写方法:

a.protected 在类自身的内部能够访问,子类能够访问,外部没法访问;

b.private 仅可在类自身的内部进行访问,子类没法访问,外部没法访问。

抽象类。抽象类没法实例化,只能做为其余类的基类。不一样于接口,抽象类能够描述类的实现细节。抽象方法在派生类中必须实现。

4.函数:

TS函数参数和返回值的类型指定以及函数重载。

指定了函数的参数类型和返回结果,函数的功能就比较特定了。可是js毕竟是动态类型的函数,js内根据参数类型不一样返回不一样的类型比较常见,因此ts提供函数重载功能

5.断言:

注意事项:

1.文件声明(开发环境对TS文件的支持):规定namespace+第三方库+管理工具+声明文件

2.项目工程化:

  a.使用webpack的文件变更检测机制,自定义启动脚本(当检测到文件发生变化时从新编译和运行入口js);

  b.使用ts-node和pm2,更改pm2的启动配置,让pm2使用ts-node直接运行ts的入口文件。

3.tsconfig.json相关:

  相似eslint,例如是否容许 使用 any 类型, 是否容许存在未使用的变量等等。

  https://www.tslang.cn/docs/handbook/compiler-options.html 

  https://www.tslang.cn/docs/handbook/error.html

2、细化模块分类:

通常状况下,模块都会有耦合。但若是耦合度太高,每每是由于模块没有细分到位。若是细化模块?举例,假若有一个模块叫Operation,里面既包含操做相关逻辑,也有操做面板逻辑。随着业务发展,操做面板逻辑愈来愈多。咱们彻底能够将操做面板逻辑单独抽成一个模块OperationPanel

化繁为简:

//1.If的使用简单粗暴,容易理解。

if ( animalType === 'dog' ) {
    console.log( 'Wang!' )
} else if ( animalType === 'cat' ) {
    console.log( 'Miao!' )
} else if ( animalType === 'bird' ) {
    console.log( 'Jiu!' )
}
//2.Switch能够看作是If的简化。

switch ( animalType ) {
    case 'dog':
      console.log( 'Wang!' )
      break
    case 'cat':
      console.log( 'Miao!' )
      break
    case 'bird':
      console.log( 'Jiu!' )
      break
}
//3.而Map针对性最强,而且最简洁、最易于维护。

const logMap = {
    dog: () => console.log( 'Wang!' ),
    cat: () => console.log( 'Miao!' ),
    bird: () => console.log( 'Jiu!' ),
}
logMap[ animalType ]()

 

3、解耦可视化库和Vue/Vuex:

class Counter {
  // # state  
  /** @type {number} */
  count = 0

  // # getters
  get countText() { return `Count is: ${ this.count }` }

  // # mutations
  /** @param {number} count*/
  SET_COUNT = count => { this.count = count }
  
  // # actions
  /** @param {number} count*/
  logCount = ( count ) => {
    this.SET_COUNT( count )
    console.log( this.countText )
  }
}

 

“使用getters和mutations”。好比定义一个模块的operationGetters.js, 里面提供各类用来获取与操做有关的常量和方法。

export const OPERATION_TYPE_A = 0
export const OPERATION_TYPE_B = 1

export const OPERATION_TITLE_MAP = {
  [ OPERATION_TYPE_A ]: 'Title A',
  [ OPERATION_TYPE_B ]: 'Title B',
}

export const getOperationTitleByType = type => OPERATION_TITLE_MAP[ type ]

定义mutations则是定义一个提供相关各类变动数据方法的文件。在维护代码的时候,查找变动方法名便可直接找到更改数据的出处。

export const SET_OPERATION_TITLE = ( operation, title ) => { operation.title = title }

-end-

相关文章
相关标签/搜索