In daily development, we often come across situations where we need to refactor, and the “Refactor” menu in VS Code provides a rich set of actions. It helps us do refactoring more efficiently.

However, this menu provides a different operation each time, if temporarily used, will bring some confusion. So often students are afraid to touch this refactoring feature.

Here, summarize some commonly used operations, for everyone to do reference.

First, warm up with a common renaming!

rename

Why rename: It’s not clear enough to make sense.

Operation steps:

  1. Select the variable name and right-click itRename SymbolOr use shortcut keysF2 ;
  2. Enter the name you want to change in the pop-up box;
  3. VSCode will change all subsequent names.

Having warmed up, let’s get down to business!

Refactoring operations

  1. Select the content you want to Refactor, right-click and select Refactor, or press Ctrl + Shift + R.

  2. Depending on what is selected, the following may appear for optional refactoring:

    • import/export

      • Convert default export to named export
      • Convert named export to default export
      • Convert namespace import to named export
      • Convert named imports to namepace export
    • Function/class

      • Move to a new File
    • Variable/expression

      • Extract constant
      • Extract constant to the closed range
      • Extract constant to the Module scope
      • Convert to optional chain expression
      • Delete unused declarations
      • Before an unused declaration
    • string

      • Convert to template string Convert to template string
    • Expression/function

      • Extract function
      • The inner function extracted from the current function
      • Extract function to the Module scope
      • Extract function to the global scope
    • Object methods

      • Generate ‘get’ and ‘set’ accessors Generate GET and SET processors
    • class

      • Generate ‘get’ and ‘set’ accessors Generate GET and SET processors
      • Convert the function to an ES2015 class
      • Convert all functions to classes
      • Method to class ‘XXX’
      • Extract a readonly field from class ‘XXX’

The magic number

Why change magic numbers? Because the actual meaning of numbers can’t be understood except in base numbers.

Objective: Define a constant value, write clear change the actual meaning of the number.

Operation:

  1. Select the magic number for reconstruction. According to needs, recommended selection:
    • Extract constant to the closed range
    • Extract constant to the Module/global scope

    Both define a constant, the former in the current function, the latter in the entire module/file;

  2. Code is extracted into a new variable and a renamed input box appears;
  3. Use all uppercase words separated by “_”.

Example: This year’s Singles’ Day lasts for 13 days, counting the end of the sales.

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

/** * change: * extract the start time START_DATE and the last number of days LASTING_DAYS as variables * if only one is used, define it in the function used; * If it is useful in more than one place, it can be considered outside the function, inside the module. * /
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);
}
Copy the code

Complex logical conditions

Why modify complex logic? Complex logic, often many conditions judgment, reading difficulty is relatively high.

Operation:

  1. Select complex logical conditions for refactoring. According to need, choose:
    • Extract constant to the closed range
    • The inner function extracted from the current function
    • Extract function to the Module/global scope
  2. The code is pulled out to a new variable/function and a renamed input box appears;
  3. Use camel names, start with is/has, and capitalize each word.

Example: Returns the number of days in a specified month

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; }}}/** * Whether leap year is often used in date handlers, so it is extracted in the outermost layer of the current module */
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);
}
Copy the code

Code snippets with comments written

I prefer the idea of code as comments. Before we write comments, we need to ask ourselves why do we need comments?

  • If the code itself is already clear, you should remove comments.
  • If you extract code snippets and name them appropriately, you can make the code easier to read, and you can remove comments.

Goal: Extract snippets of code into functions that are named after the specific functionality of the code block.

Operation:

  1. Select the code block and Refactor. Options:
    • The inner function extracted from the current function

Example: Ajax request

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;

  // Create - non-IE6 - First step
  if (window.XMLHttpRequest) {
    xhr = new window.XMLHttpRequest();
  } else { // Internet Explorer 6 or later
    xhr = new window.ActiveXObject('Microsoft.XMLHTTP');
  }

  // Connect and send - step 2
  if (options.type === 'GET') {... }else if (options.type === 'POST') {... }// Receive - step 3
  xhr.onreadystatechange = function () {
    if(xhr.readyState === READY_STATE) { ... }}; }/ / modified
function ajax(options) {...let xhr;

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

  function create() {... }function connectAndSend() {... }function recieve() {...}
}
Copy the code

Overlong function

Functions are split into external functions and then called internally.

Operation:

  1. To select code block refactoring, select:
    • Extract function to the Module/Global scope
  2. The code block generates a function and takes the necessary parameters

Example: In the previous example, you could separate the Ajax receiver module into a module function

function ajax(options) {... create(); recieve(); connectAndSend(options, xhr, params); }function connectAndSend(options, xhr, params) {
  if (options.type === 'GET') {... }else if (options.type === 'POST') {... }}Copy the code

Duplicate code/too long file

Operation:

  1. Select Code block refactoring and Move to a new file.
  2. The code is migrated to a file with the current function/class as the filename; If there are more than one class/function, the first class/function is named
  3. Expose functions/classes as export;
  4. Import functions/classes in the original file.

Example: date handlers:

After moving to a new file:

In index.js, you can jump to the defined code, but it’s not actually introduced.

Rename, fix import/export;

import/export

Conversion of default and names, namespaces and names.

// named
export function nextMonthDay(year, month) {}
​
// default
export default function nextMonthDay(year, month) {}
​
// namepace 
import * as refactor from './refactor';
​
// named
import { nextMonthDay } from './refactor';
Copy the code

Object methods

Generate GET and SET handlers

const person = {
  age: 32
};
​
// Generate get and set handlers
const person = {
  _age: 32.get age() {
    return this._age;
  },
  set age(value) {
    this._age = value; }};Copy the code

Template string

String concatenation, fast conversion to template string:

class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return this.firstName + ' ' + this.lastName; }}// Template string
class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  getFullName() {
    return `The ${this.firstName} The ${this.lastName}`; }}Copy the code

class

Generate get and SET handlers, similar to the result of object methods.

The Method extracted to class XXX is similar to the Method extracted from the commented code above.

I will not repeat it here.

ES 2015 class transformation is provided to support prototype method transformation.

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
class Person {
  constructor() {
    this.age = 32;
  }
  getAge() {
    return this.age;
  }
  setAge(value) {
    return this.age = value; }}Copy the code

conclusion

There are many other ways to refactor code, and here are some of them. Hope to help you.

For the rest, you can click on the refactoring menu as you refactor your code and see if you’re surprised.