By ryanmcdermott

Like it and see. Make it a habit

In this paper,GitHub Github.com/qq449245884…Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.

In development, variable names, function names should be clear, as far as possible to see the name can let people know your intention, so variable and function naming is very important, today to look at how to name variables and functions in a more elegant way.

variable

Use meaningful and pronounceable variable names

// const yyyYMmdstr = moment().format()"YYYY/MM/DD"); Const currentDate = moment().format()"YYYY/MM/DD");
Copy the code

Use the same vocabulary for variables of the same type

// Bad way to write getUserInfo(); getClientData(); getCustomerRecord(); // A good way to write this is getUser();Copy the code

Use searchable names

We read a lot more than we write, so naming things too casually not only makes maintenance difficult, but also hurts the developers who read our code. Make your variable names readable, and tools like Buddy. Js and ESLint can help identify unnamed constants.

// What is 86400000 used for?setTimeout(blastOff, 86400000); Const zipperegex = $zipperegex; const zipperegex = $zipperegex;setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
Copy the code

Use explanatory variables

// const address ="One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?) \s*(\d{5})? $/; saveCityZipCode( address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2] ); // Const address ="One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?) \s*(\d{5})? $/; const [_, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode);Copy the code

Avoid guesswork

Explicit is used for implicit

// const locations = ["Austin"."New York"."San Francisco"];
locations.forEach(l => {
  doStuff();
  doSomeOtherStuff(); / /... / /... / /... // Wait, what is "l"? dispatch(l); // Const locations = ["Austin"."New York"."San Francisco"];
locations.forEach(location => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  dispatch(location);
});
Copy the code

Everyone said there was no project on your resume, so I found one and gave it away【 Construction tutorial 】.

There is no need to add unnecessary context

If the class/object name is already stated, there is no need to repeat it in the variable name.

// const Car = {carMake:"Honda",
  carModel: "Accord",
  carColor: "Blue"
};

function paintCar(car) {
  car.carColor = "Red"; } // const Car = {make:"Honda",
  model: "Accord",
  color: "Blue"
};

function paintCar(car) {
  car.color = "Red";
}

Copy the code

Use default arguments instead of logic or (and) operations

// It's a bad way to writefunction createMicrobrewery(name) {
  const breweryName = name || "Hipster Brew Co."; / /... } // Good way to write itfunction createMicrobrewery(name = "Hipster Brew Co."{/ /... }Copy the code

function

Function arguments (ideally 2 or fewer)

Limiting the number of function arguments is important because it makes it easier to test functions. Having more than three parameters results in a combinatorial explosion, and a large number of different cases must be tested with each individual parameter.

One or two parameters is ideal, and three parameters should be avoided if possible. In addition, there should be mergers. In most cases, arguments larger than three can be replaced with objects.

// It's a bad way to writefunction createMenu(title, body, buttonText, cancellable) {
  // ...
}

createMenu("Foo"."Bar"."Baz".true); // Good way to write itfunction createMenu({ title, body, buttonText, cancellable }) {
  // ...
}

createMenu({
  title: "Foo",
  body: "Bar",
  buttonText: "Baz",
  cancellable: true
});
Copy the code

The function should only do one thing

This is by far the most important rule in software engineering. When functions do more than one thing, they are harder to compose, test, and reason about. When a function can be isolated as an operation, it can be easily refactored and the code reads more cleanly.

// It's a bad way to writefunction emailClients(clients) {
  clients.forEach(client => {
    const clientRecord = database.lookup(client);
    if(clientRecord.isActive()) { email(client); }}); } // Good way to write itfunction emailActiveClients(clients) {
  clients.filter(isActiveClient).forEach(email);
}

function isActiveClient(client) {
  const clientRecord = database.lookup(client);
  return clientRecord.isActive();
}
Copy the code

The function name should state its purpose

// It's a bad way to writefunctionaddToDate(date, month) { // ... } const date = new Date(); AddToDate (date, 1); // Good way to write itfunction addMonthToDate(month, date) {
  // ...
}

const date = new Date();
addMonthToDate(1, date);
Copy the code

Functions should have only one level of abstraction

When there is more than one abstraction level function, it means that the function is doing too much and needs to be broken up for reusability and easier testing.

// It's a bad way to writefunctionparseBetterJSAlternative(code) { const REGEXES = [ // ... ] ; const statements = code.split(""); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { // ... }); }); const ast = []; tokens.forEach(token => { // lex... }); ast.forEach(node => { // parse... }); } // Good way to write itfunction parseBetterJSAlternative(code) {
  const tokens = tokenize(code);
  const syntaxTree = parse(tokens);
  syntaxTree.forEach(node => {
    // parse...
  });
}

functiontokenize(code) { const REGEXES = [ // ... ] ; const statements = code.split(""); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { tokens.push(/* ... * /); }); });return tokens;
}

functionparse(tokens) { const syntaxTree = []; tokens.forEach(token => { syntaxTree.push(/* ... * /); });return syntaxTree;
}
Copy the code

Everyone said there was no project on your resume, so I found one and gave it away【 Construction tutorial 】.

Remove duplicate code

Try to avoid duplicate code, duplicate code is bad, it means that if we need to change some logic, we need to change a lot of things.

Often, there is duplicate code because there are two or more slightly different things that have a lot in common, but the differences between them force us to write two or more independent functions to do many of the same things. Removing duplicate code means creating an abstraction that can handle this different set of things with just one function/module/class.

Getting the abstraction right is crucial, which is why we should follow the SOLID principles outlined in the Classes section. Bad abstractions can be worse than repetitive code, so be careful! Having said all that, if you can make a good abstraction, do it! Don’t repeat yourself, or you’ll find yourself updating multiple places any time you want to change something.

The six principles of design patterns are:

  • 1. The Principle of Single Responsibility
  • Open Closed Principle: The Open Closed Principle
  • Substitution Principle: Liskov Substitution Principle
  • The Law of Demeter
  • Interface Segregation Principle: Interface Segregation Principle
  • Dependence Inversion Principle

When the first letters of these six principles are combined (the two L’s make one), SOLID represents the benefits of these six principles combined: the creation of stable, flexible, robust designs. Let’s take a look at each of these six design principles.

Bad way to write it

function showDeveloperList(developers) {
  developers.forEach(developer => {
    const expectedSalary = developer.calculateExpectedSalary();
    const experience = developer.getExperience();
    const githubLink = developer.getGithubLink();
    const data = {
      expectedSalary,
      experience,
      githubLink
    };

    render(data);
  });
}

function showManagerList(managers) {
  managers.forEach(manager => {
    const expectedSalary = manager.calculateExpectedSalary();
    const experience = manager.getExperience();
    const portfolio = manager.getMBAProjects();
    const data = {
      expectedSalary,
      experience,
      portfolio
    };

    render(data);
  });
}
Copy the code

Good way to write it

functionshowEmployeeList(employees) { employees.forEach(employee => { const expectedSalary = employee.calculateExpectedSalary();  const experience = employee.getExperience(); const data = { expectedSalary, experience }; switch (employee.type) {case "manager":
        data.portfolio = employee.getMBAProjects();
        break;
      case "developer":
        data.githubLink = employee.getGithubLink();
        break;
    }

    render(data);
  });
}
Copy the code

useObject.assignSetting the Default object

Bad way to write it

const menuConfig = {
  title: null,
  body: "Bar",
  buttonText: null,
  cancellable: true
};

function createMenu(config) {
  config.title = config.title || "Foo";
  config.body = config.body || "Bar";
  config.buttonText = config.buttonText || "Baz"; config.cancellable = config.cancellable ! == undefined ? config.cancellable :true;
}

createMenu(menuConfig);
Copy the code

Good way to write it

const menuConfig = {
  title: "Order",
  // User did not include 'body' key
  buttonText: "Send",
  cancellable: true
};

function createMenu(config) {
  config = Object.assign(
    {
      title: "Foo",
      body: "Bar",
      buttonText: "Baz",
      cancellable: true
    },
    config
  );

  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}

createMenu(menuConfig);
Copy the code

Everyone said there was no project on your resume, so I found one and gave it away【 Construction tutorial 】.

Do not use flags as function arguments

The flag tells the user that this function can do multiple tasks and that the function should do one thing. If functions follow different code paths based on booleans, split them.

// It's a bad way to writefunction createFile(name, temp) {
  if (temp) {
    fs.create(`./temp/${name}`);
  } else{ fs.create(name); }} // Good way to writefunction createFile(name) {
  fs.create(name);
}

function createTempFile(name) {
  createFile(`./temp/${name}`);
}
Copy the code

Avoid Side effects (Part 1)

If a function does nothing but take one value and return another or more values, it can have side effects. The side effects could be writing to files, changing some global variables, or accidentally sending all your money to a stranger.

Bad way to write it


let name = "Ryan McDermott";

function splitIntoFirstAndLastName() {
  name = name.split(""); } splitIntoFirstAndLastName(); console.log(name); / / /'Ryan'.'McDermott'];
Copy the code

Good way to write it

function splitIntoFirstAndLastName(name) {
  return name.split("");
}

const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name);

console.log(name); // 'Ryan McDermott'; console.log(newName); / / /'Ryan'.'McDermott'];
Copy the code

Avoid Side effects (Part 2)

In JavaScript, primitive type values are passed by value, while objects/arrays are passed by reference. For objects and arrays, if a function changes in the shopping cart array (for example, by adding an item to purchase), any other function that uses that shopping cart array will be affected by the addition. That might be great, but it might not be. Imagine a bad situation:

The user clicks the Buy button, which invokes a purchase function, which then issues a network request and sends the CART array to the server. Because of the poor network connection, the Purchase function must continually retry the request. Now, what if a user accidentally clicks the “Add to Cart” button on an item they don’t actually need before the web request starts? If this happens and the network request starts, the purchase function will send the accidentally added item because it has a reference to the shopping cart array that the addItemToCart function modifies by adding.

A good solution is that addItemToCart always clones the CART array, edits it, and then returns the clone. This ensures that other functions referenced by the shopping cart are not affected by any changes.

There are two things to note about this approach:

1. There may be cases where we do need to modify the input object, but when we use this programming practice, we find that this is very rare, and most things can be modified without side effects.

2. Cloning large objects can be very expensive in terms of performance. Fortunately, this isn’t a big problem in practice, because there are a lot of great libraries that make this kind of programming fast and don’t take up as much memory as manually cloning objects and arrays.

// Const addItemToCart = (cart, item) => {cart. Push ({item, date: date.now ()}); }; Const addItemToCart = (cart, item) => {return [...cart, { item, date: Date.now() }];
};
Copy the code

Don’t write global functions

Contaminating global variables is a bad practice in JS, because there may be conflicts with another library, and users of the API will be useless until they encounter an exception in their production. Let’s consider an example: What if we wanted to extend JS’s native Array method to have a diff method that shows the difference between two arrays? You can write the new function to array.prototype, but it might conflict with another library that is trying to do the same thing. What if other libraries just use diff to find the difference between the first and last element of an array? That’s why it’s better to just use ES6 classes and simply extend Array globally.

Array.prototype.diff = array.prototype.diff =function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  returnthis.filter(elem => ! hash.has(elem)); }; Class SuperArray extends Array {diff(comparisonArray) {consthash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));
  }
}
Copy the code

Use functional programming rather than imperative

JavaScript is not a functional language like Haskell, but it has a functional style. Functional languages can be simpler and easier to test. If you can, try to enjoy this programming style.

Bad way to write it

const programmerOutput = [
  {
    name: "Uncle Bobby",
    linesOfCode: 500
  },
  {
    name: "Suzie Q",
    linesOfCode: 1500
  },
  {
    name: "Jimmy Gosling",
    linesOfCode: 150
  },
  {
    name: "Gracie Hopper",
    linesOfCode: 1000
  }
];

let totalOutput = 0;

for (let i = 0; i < programmerOutput.length; i++) {
  totalOutput += programmerOutput[i].linesOfCode;
}
Copy the code

Good way to write it

const programmerOutput = [
  {
    name: "Uncle Bobby",
    linesOfCode: 500
  },
  {
    name: "Suzie Q",
    linesOfCode: 1500
  },
  {
    name: "Jimmy Gosling",
    linesOfCode: 150
  },
  {
    name: "Gracie Hopper",
    linesOfCode: 1000
  }
];

const totalOutput = programmerOutput.reduce(
  (totalLines, output) => totalLines + output.linesOfCode,
  0
);
Copy the code

Encapsulation condition

// It's a bad way to writeif (fsm.state === "fetching"&& isEmpty(listNode)) { // ... } // Good way to write itfunction shouldShowSpinner(fsm, listNode) {
  return fsm.state === "fetching" && isEmpty(listNode);
}

if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
  // ...
}
Copy the code

Everyone said there was no project on your resume, so I found one and gave it away【 Construction tutorial 】.

Avoid nonconditions

// It's a bad way to writefunction isDOMNodeNotPresent(node) {
  // ...
}

if(! isDOMNodeNotPresent(node)) { // ... } // Good way to write itfunction isDOMNodePresent(node) {
  // ...
}

if (isDOMNodePresent(node)) {
  // ...
}
Copy the code

Avoid using too many conditions

It seems an impossible task. Upon hearing this, most people will say, “How can I do anything without the if statement?” The answer is that you can use polymorphism in many situations to accomplish the same task.

The second question is usually, “That’s great, but why would I do that?” The answer is the concept mentioned above: a function should only do one thing. When classes and functions have if statements, they are telling your users that the function does more than one thing.

Bad way to write it

class Airplane {
  // ...
  getCruisingAltitude() {
    switch (this.type) {
      case "777":
        return this.getMaxAltitude() - this.getPassengerCount();
      case "Air Force One":
        return this.getMaxAltitude();
      case "Cessna":
        returnthis.getMaxAltitude() - this.getFuelExpenditure(); }}}Copy the code

Good way to write it

class Airplane {
  // ...
}

class Boeing777 extends Airplane {
  // ...
  getCruisingAltitude() {
    return this.getMaxAltitude() - this.getPassengerCount();
  }
}

class AirForceOne extends Airplane {
  // ...
  getCruisingAltitude() {
    return this.getMaxAltitude();
  }
}

class Cessna extends Airplane {
  // ...
  getCruisingAltitude() {
    returnthis.getMaxAltitude() - this.getFuelExpenditure(); }}Copy the code

Avoiding type checking

JavaScript is untyped, which means functions can accept arguments of any type. Sometimes we get frustrated with this freedom and want to do type checking in functions. There are ways to avoid this. The first thing to consider is a consistent API.

// It's a bad way to writefunction travelToTexas(vehicle) {
  if (vehicle instanceof Bicycle) {
    vehicle.pedal(this.currentLocation, new Location("texas"));
  } else if (vehicle instanceof Car) {
    vehicle.drive(this.currentLocation, new Location("texas")); }} // Good way to writefunction travelToTexas(vehicle) {
  vehicle.move(this.currentLocation, new Location("texas"));
}
Copy the code

Don’t over-optimize

Modern browsers do a lot of optimization at runtime. A lot of times, if you’re optimizing, you’re just wasting your time. There are great resources to see where optimization is lacking, and we just need to focus on the areas that need to be optimized.

// Bad notation // On older browsers, each iteration using no cache "list.length" is expensive // recalculated for "list.length". In modern browsers, this is optimizedfor (leti = 0, len = list.length; i < len; i++) { // ... } // Good way to write itfor (let i = 0; i < list.length; i++) {
  // ...
}

Copy the code

The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original text: github.com/ryanmcdermo…


communication

This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.