代码健壮性

健壮性:代码在发生错误的时候,尽可能的减少错误的后果。
健壮性差的代码的表现:

  1. 写代码3小时,改代码5小时。
  2. 一不小心玩崩溃整个系统。

健壮性:

  1. 参数层面
  2. 易错代码
  3. 属性权限

    参数层面

    举个栗子: ```javascript // 栗子1 ————————————————————

// 坏味道 functin add(a, b) { return a + b; } add(1, 2); // => 3 let result = add(1); // => 1 + undefined => NaN // 此时查找错误比较困难,不容易发现出现错误的地方。 axios.request(result); // => 400 错误

// 好味道 // 通过跑出错误就能发现是这个地方出错了 function add(a, b) { if (typeof a === ‘number’ && typeof b === ‘number’) { return a + b; } else { throw new Error(‘参数 a 或者 b 不是一个数字!’); } }

// 栗子2 ————————————————————

// 配置对象参数 => 选线合并 // 如果必传参数没有传入,报错时,错误也不好检查 function Vue(config) { // 默认参数 let _default = { el: ‘’, template: ‘’, };

for (let item in config) { _default[item] = config[item]; } }

// el , template 为必填参数 new Vue({ el: ‘’, template: ‘’, });

// 栗子3 ————————————————————

// 传入的参数是某个类的实例 => instanceof function Class1() {

}

function b(obj) { if (obj instanceof Class1) { // 进行操作 } else { throw new Error(‘传入的参数 obj 必须是类 Class1 的实例!’); } }

// 栗子4 ————————————————————

// js 特有的健壮性考虑 // JavaScript中一个函数除了是一个方法,还可能是一个类。 // a(); a 是方法时,this 指向 window // new a(); a 是类时,this 指向类的实例 function a() { if (this instanceof a) { // 实例化类的操作 this.aa = 1; } else { return new a(); } }

  1. <a name="SW8QX"></a>
  2. ## 易错代码
  3. 代码错误不是自己能控制的。一旦某个地方出现了错误,会中断整个程序。
  4. 1. 读取文件
  5. 1. 取值
  6. 1. 请求
  7. 1. 后端是整个服务,使用错误日志
  8. ```javascript
  9. let a = {
  10. b: {
  11. c: 1
  12. }
  13. }
  14. let result = a.b.c;
  15. // 如果a是后端返回,切丢失了数据,返回数据如下
  16. a = {};
  17. // 此时 a.b.c 会报错,终止代码执行。
  18. // 后端使用 try catch 防止错误终端服务,并将错误发送到错误日志。
  19. // 前端也可以使用 try catch 包裹易错代码块,不让错误代码终止程序。
  20. try {
  21. } catch(e) {
  22. }

变量权限

定义的变量是否可以被更改。
例如:vue-router 中 this.$router 是不可被更改的。
使用 Object.defineProperty()

  1. // Object.defineProperty(obj, prop, descriptor)
  2. // Object.defineProperty() 方法会直接在一个对象上定义一个新属性,
  3. // 或者修改一个对象的现有属性,并返回此对象。
  4. // 详细了解 Object.defineProperty 用法,
  5. // 请查看文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
  6. const object1 = {};
  7. Object.defineProperty(object1, 'property1', {
  8. value: 42,
  9. writable: false
  10. });
  11. object1.property1 = 77;
  12. // throws an error in strict mode
  13. console.log(object1.property1);
  14. // expected output: 42
  15. // ----------------------
  16. let _router = {};
  17. Object.defineProperty(this, '$router', {
  18. // 只设置 getter 不设置 setter 时,属性不会被修改
  19. get: function() {
  20. return _router;
  21. }
  22. });

可读性

  1. 语义化
    1. 命名要能表达出变量、方法、类的作用;
    2. 名字长一点没关系,咱们有代码混淆和压缩。
  2. 命名规范
    1. 遵守前端命名规范
  3. 结构清晰

    1. js 容易产生结构不清晰的地方:
      1. 回调函数
      2. if-else
    2. promise的推出是为了优化代码结构
    3. 连续回调 => 回调地狱
    4. if-else 可以使用策略模式/状态模式解决

      1. // 回调地狱
      2. $.ajax({
      3. success: function() {
      4. $.ajax({
      5. success: function() {
      6. $.ajax({
      7. success: function () {
      8. }
      9. });
      10. }
      11. });
      12. }
      13. });

      可复用性

      比较考验程序员能力

  4. Dry原则

  5. 逻辑复用,提取代码
    1. 提取公用部分作为一个方法
    2. 享元模式
  6. 创建公用模板

    1. 父类
    2. 组合

      可扩展性

      最考验程序员能力。
      需求是一只在变化的,应对需求修改。
  7. 模块分明

    1. 职责分明
  8. 耦合度低
  9. 合适的扩张技巧 - 设计模式