Refatoração de front-end com VS Code

No desenvolvimento diário, muitas vezes encontramos a necessidade de refatorar, e o menu "Refatorar" no VS Code nos fornece uma variedade de operações. Isso pode nos ajudar a concluir o trabalho de refatoração com mais eficiência.

No entanto, as operações fornecidas por este menu são diferentes a cada vez, se você usá-lo temporariamente, ele trará alguns problemas. Portanto, muitas vezes há alunos que não ousam tocar nessa função de refatoração.

Aqui, algumas operações comumente usadas são resumidas para sua referência.

Primeiro, uma renomeação comum, aqueça!

Renomear

Por que renomear: A nomenclatura não é clara o suficiente para as pessoas entenderem.

Degraus:

  1. Selecione o nome da variável, clique com o botão direito do mouse para selecionar 重命名符号(Rename Symbol)ou use as teclas de atalho F2 ;
  2. Digite o nome que deseja modificar na caixa pop-up;
  3. O VSCode mudará todos os nomes relacionados subsequentes.

image-20220302194921502.png

O aquecimento acabou, vamos ao que interessa!

operação de refatoração

image-20220302140642013.png

  1. Selecione o conteúdo a ser reconstruído, clique com o botão direito do mouse para selecionar 重构(Refactor)ou use Ctrl + Shift + R.

  2. Dependendo do que for selecionado, as seguintes opções podem aparecer para refatoração:

    • importar/exportar

      • Converter exportação padrão em exportação nomeada
      • Converter exportação nomeada para exportação padrão
      • Converter importação de namespace em exportação nomeada
      • Converter importações nomeadas em exportação de namespace
    • função/classe

      • Mover para um novo arquivo
    • variável/expressão

      • Extrair constante
      • constante extraída para o escopo anexo
      • Constante extraída para o escopo do módulo
      • Converter em expressão de cadeia opcional
      • remover declarações não utilizadas
      • antes da declaração não utilizada
    • corda

      • Converter em string de modelo Converter em string de modelo
    • expressão/função

      • Extrair função
      • A função interna extraída na função atual
      • Funções extraídas para o escopo do módulo
      • função extraída para escopo global
    • 对象方法

      • generate ‘get’ and ‘set’ accessors 生成get、set处理器
      • generate ‘get’ and ‘set’ accessors 生成get、set处理器
      • 将函数转换成 ES2015类
      • 将所有函数转换成类
      • 提取到 class 'xxx' 中的 Method
      • 提取到 class 'xxx' 中的 readonly field

魔法数字

为什么要修改魔法数字?因为除进制数之外,数字的实际意义无法被人看懂。

目标:定义一个常量值,写清楚改数字的实际意义。

操作:

  1. 选中魔法数字进行重构。根据需要,推荐选择:
    • 提取到封闭范围的 constant
    • 提取到 Module/global 范围的 constant
    两者都会定义一个常量,前者定义在当前函数内,后者则是整个模块/文件中;
  2. 代码抽取到新的变量中,并出现重命名的输入框;
  3. 使用全大写单词,单词使用“_”间隔。

例子:今年双十一持续13天,计算除双十一促销结束的时间。

function promotionEndDate() {
  return new Date(new Date('2022-11-11').getTime() + 13 * 60 * 60 * 24 * 1000);
}

/**
 * 修改后:
 * 将开始时间 START_DATE,持续的天数 LASTING_DAYS 抽取出来做成变量
 * 如果只有一处使用,则在使用到的函数内定义;
 * 如果多处都有用,可以考虑放在函数外,模块内。
 */
function promotionEndDate() {
    const START_DATE = '2022-11-11';
    const LASTING_DAYS = 13;
    return new Date(new Date(START_DATE).getTime() + LASTING_DAYS * 60 * 60 * 24 * 1000);
}
复制代码

复杂的逻辑条件

为什么要修改复杂逻辑?复杂的逻辑,往往条件判断繁多,阅读难度比较高。

操作:

  1. 选中复杂的逻辑条件进行重构。根据需要,选择:
    • 提取到封闭范围的 constant
    • 提取到当前函数里的 inner function
    • 提取到 Module/global 范围的 function
  2. 代码抽离到一个新的变量/函数中,并出现重命名的输入框;
  3. 使用驼峰命名,使用 is/has 起头,每个单词首字母大写。

例子:返回指定的某个月有多少天

function monthDay(year, month) {
    var day31 = [1, 3, 5, 7, 8, 10, 12];
    var day30 = [4, 6, 9, 11];
    if (day31.indexOf(month) > -1) {
        return 31;
    } else if (day30.indexOf(month) > -1) {
        return 30;
    } else {
        if ((year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)) {
            return 29;
        } else {
            return 28;
        }
    }
}

/**
 * 修改后
 * 是否闰年在日期处理函数中会经常使用,所以将其提取到当前模块的最外层了
 */
function monthDay(year, month) {
    ...
    if (day31.indexOf(month) > -1) {
        return 31;
    } else if (day30.indexOf(month) > -1) {
        return 30;
    } else {
        if (isLeapYear(year)) {
            return 29;
        } else {
            return 28;
        }
    }
}

function isLeapYear(year) {
    return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}
复制代码

写了注释的代码片段

更推荐代码即注释的理念。我们写注释之前要想明白为什么需要注释?

  • 如果代码本身已经很清晰,应该删除注释。
  • 如果抽取代码片段,取个合适的名字,能让代码易于阅读,也可以删除注释。

目标:将代码片段抽取出来做成函数,函数以此代码块的具体功能做命名。

操作:

  1. 选择代码块,重构(Refactor)。选择:
    • 提取到当前函数里的 inner function

例子:ajax 请求

function ajax(options) {
  options = options || {};
  options.type = (options.type || 'GET').toUpperCase();
  options.dataType = options.dataType || 'json';
  const READY_STATE = 4;
  const NET_STATUS = {
    OK: 200,
    RIDERCT: 300
  };
  const params = this.formatAjaxParams(options.data);
  let xhr;

  // 创建 - 非IE6 - 第一步
  if (window.XMLHttpRequest) {
    xhr = new window.XMLHttpRequest();
  } else { // IE6及其以下版本浏览器
    xhr = new window.ActiveXObject('Microsoft.XMLHTTP');
  }

  // 连接 和 发送 - 第二步
  if (options.type === 'GET') {
    ...
  } else if (options.type === 'POST') {
    ...
  }
  
  // 接收 - 第三步
  xhr.onreadystatechange = function () {
    if (xhr.readyState === READY_STATE) {
      ...
    }
  };
}

// 修改后
function ajax(options) {
  ...
  let xhr;

  create();
  connectAndSend();
  recieve();

  function create() {...}
  function connectAndSend() {...}
  function recieve() {...}
}
复制代码

过长的函数

功能拆分做成外部函数,再在内部调用。

操作:

  1. 选择代码块重构,选择:
    • 提取到 Module/Global 范围的 function
  2. O bloco de código gera uma função com os parâmetros necessários

Exemplo: No exemplo anterior, o módulo receptor do ajax pode ser separado na função do módulo

function ajax(options) {
  ...

  create();
  recieve();
  connectAndSend(options, xhr, params);
}
function connectAndSend(options, xhr, params) {
  if (options.type === 'GET') {
    ...
  } else if (options.type === 'POST') {
    ...
  }
}
复制代码

Código duplicado/arquivos muito longos

operar:

  1. Selecione a refatoração do bloco de código, selecione Move to a new file ;
  2. O código será migrado para o arquivo com a função/classe atual como nome do arquivo; se houver várias classes/funções, a primeira classe/função será especificada
  3. Expor funções/classes usando exportação;
  4. Use import para importar funções/classes no arquivo original.

Exemplo: função de manipulação de data:

image-20220302191918541.png

Depois de passar para o novo arquivo:

image-20220302192102375.png

Em index.js, você também pode pular para o código definido, mas ele não é realmente introduzido.

image-20220302192443818.png

Renomear, corrigir importação/exportação;

image-20220302193939854.png

importar/exportar

transformações padrão e de nomenclatura, namespace e nomenclatura.

// named
export function nextMonthDay(year, month) {}
​
// default
export default function nextMonthDay(year, month) {}
​
// namepace 
import * as refactor from './refactor';
​
// named
import { nextMonthDay } from './refactor';
复制代码

método do objeto

Gerar processadores get e set

const person = {
  age: 32
};
​
// 生成get、set处理器
const person = {
  _age: 32,
  get age() {
    return this._age;
  },
  set age(value) {
    this._age = value;
  },
};
复制代码

seqüência de modelo

Concatenação de strings, converta rapidamente para string de modelo:

class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}
​
// 模板字符串
class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}
复制代码

amável

Gere manipuladores get e set , semelhantes aos resultados dos métodos de objeto.

O Método extraído para a classe xxx é semelhante ao código escrito nos comentários acima e extraído do código repetido.

Não será repetido aqui.

Fornece transformações de classe ES 2015 e suporta transformações de método de protótipo.

const Person = function() {
  this.age = 32;
};
Person.prototype.getAge = function() {
  return this.age;
}
Person.prototype.setAge = function(value) {
  return this.age = value;
}
​
// ES 2015 类
class Person {
  constructor() {
    this.age = 32;
  }
  getAge() {
    return this.age;
  }
  setAge(value) {
    return this.age = value;
  }
}
复制代码

Resumir

Existem muitas maneiras de refatorar o código, aqui estão algumas delas. Espero ser útil.

Para o restante do conteúdo, você pode clicar mais no menu de refatoração ao refatorar o código para ver se há alguma surpresa.

Acho que você gosta

Origin juejin.im/post/7070695967577604133
Recomendado
Clasificación