前端代码规范

前端代码规范

变量

1、使用有意义且易懂的变量名

Bad:
const yyyymmdstr = moment().format("YYYY/MM/DD");
Good:
const currentDate = moment().format("YYYY/MM/DD");

2、对相同类型的变量使用相同的根词汇

Bad:
getUserInfo(); getClientData(); getCustomerRecord();
Good:
getUserInfo(); getUserData(); getUserRecord();

3、编写的代码是可读和可搜索的

Bad:
// What the heck is 86400000 for? 
setTimeout(blastOff, 86400000);
Good:
// Declare them as capitalized named constants. 
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000; 
setTimeout(blastOff, MILLISECONDS_PER_DAY);

4、使用解释变量

Bad:

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

Good:

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

5、显式优于隐式

Bad:

const locations = ["Austin", "New York", "San Francisco"]; 
locations.forEach(l => {   
doStuff();   
doSomeOtherStuff(); 
   // Wait, what is `l` for again? 
  dispatch(l); });

Good:

const locations = ["Austin", "New York", "San Francisco"]; 
locations.forEach(location => { 
  doStuff(); 
  doSomeOtherStuff(); 
 dispatch(location); 
});

6、如果你的类/对象名告诉了你什么,不要在变量名中重复。

Bad:

const Car = {   carMake: "Honda",   carModel: "Accord",   carColor: "Blue" }; 
function paintCar(car, color) {   
car.carColor = color; 
}

Good:

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

7、默认参数是更干净的写法

Bad:

function createMicrobrewery(name) 
{   const breweryName = name || "Hipster Brew Co.";  
 // ... }

Good:

function createMicrobrewery(name = "Hipster Brew Co.") 
{   // ... }

方法

1、参数数量小于等于2

Bad:

function createMenu(title, body, buttonText, cancellable) {
  // ...
}
createMenu("Foo", "Bar", "Baz", true);

Good:

function createMenu({ title, body, buttonText, cancellable }) {
  // ...
}
createMenu({
  title: "Foo",
  body: "Bar",
  buttonText: "Baz",
  cancellable: true
});

2、单一功能性

Bad:

function emailClients(clients) {
  clients.forEach(client => {
    const clientRecord = database.lookup(client);
    if (clientRecord.isActive()) {
      email(client);
    }
  });
}

Good:

function emailActiveClients(clients) {
  clients.filter(isActiveClient).forEach(email);
}
function isActiveClient(client) {
  const clientRecord = database.lookup(client);
  return clientRecord.isActive();
}

3、函数名告诉我们他是做什么的

Bad:

function addToDate(date, month) {
  // ...
}


const date = new Date();
// It's hard to tell from the function name what is added
addToDate(date, 1);

Good:

function addMonthToDate(month, date) {
  // ...
}
const date = new Date();
addMonthToDate(1, date);

4、删除重复代码

Bad:

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);
  });
}

Good:

function showEmployeeList(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);
  });
}

5、使用Object.assign设置默认对象

Bad:

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);

Good:

const menuConfig = {
  title: "Order",
  // User did not include 'body' key
  buttonText: "Send",
  cancellable: true
};
function createMenu(config) {
  let finalConfig = Object.assign(
    {
      title: "Foo",
      body: "Bar",
      buttonText: "Baz",
      cancellable: true
    },
    config
  );
  return finalConfig
  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}
createMenu(menuConfig);

6、不要将标志用作函数参数

Bad:

function createFile(name, temp) {
  if (temp) {
    fs.create(`./temp/${name}`);
  } else {
    fs.create(name);
  }
}

Good:

function createFile(name) {
  fs.create(name);
}
function createTempFile(name) {
  createFile(`./temp/${name}`);
}

7、避免副作用函数

Bad:

// Global variable referenced by following function.
// If we had another function that used this name, now it'd be an array and it could break it.
let name = "Ryan McDermott";
function splitIntoFirstAndLastName() {
  name = name.split(" ");
}
splitIntoFirstAndLastName();
console.log(name); // ['Ryan', 'McDermott'];

Good:

function splitIntoFirstAndLastName(name) {
  return name.split(" ");
}
const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name);
console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];

8、条件封装为函数

Bad:

if (fsm.state === "fetching" && isEmpty(listNode)) {
  // ...
}

Good:

function shouldShowSpinner(fsm, listNode) {
  return fsm.state === "fetching" && isEmpty(listNode);
}
if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
  // ...
}

9、避免否定条件

Bad:

function isDOMNodeNotPresent(node) {
  // ...
}
if (!isDOMNodeNotPresent(node)) {
  // ...
}

Good:

function isDOMNodePresent(node) {
  // ...
}
if (isDOMNodePresent(node)) {
  // ...
}

10、移除 deadcode

Bad:

function oldRequestModule(url) {
  // ...
}
function newRequestModule(url) {
  // ...
}
const req = newRequestModule;
inventoryTracker("apples", req, "www.inventory-awesome.io");

Good:

function newRequestModule(url) {
  // ...
}
const req = newRequestModule;
inventoryTracker("apples", req, "www.inventory-awesome.io");

对象和数据结构

1、用set get修改数据

Bad:

function makeBankAccount() {
  // ...
  return {
    balance: 0
    // ...
  };
}
const account = makeBankAccount();
account.balance = 100;

Good:

function makeBankAccount() {
  // this one is private
  let balance = 0;
  // a "getter", made public via the returned object below
  function getBalance() {
    return balance;
  }
  // a "setter", made public via the returned object below
  function setBalance(amount) {
    // ... validate before updating the balance
    balance = amount;
  }
  return {
    // ...
    getBalance,
    setBalance
  };
}
const account = makeBankAccount();
account.setBalance(100);

Class

1、方法使用链式调用

Bad:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }
  setMake(make) {
    this.make = make;
  }
  setModel(model) {
    this.model = model;
  }
  setColor(color) {
    this.color = color;
  }
  save() {
    console.log(this.make, this.model, this.color);
  }
}
const car = new Car("Ford", "F-150", "red");
car.setColor("pink");
car.save();

Good:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }
  setMake(make) {
    this.make = make;
    // NOTE: Returning this for chaining
    return this;
  }
  setModel(model) {
    this.model = model;
    // NOTE: Returning this for chaining
    return this;
  }
  setColor(color) {
    this.color = color;
    // NOTE: Returning this for chaining
    return this;
  }
  save() {
    console.log(this.make, this.model, this.color);
    // NOTE: Returning this for chaining
    return this;
  }
}
const car = new Car("Ford", "F-150", "red").setColor("pink").save();

异步请求

Use Promises, not callbacks

Bad:

import { get } from "request";
import { writeFile } from "fs";
get(
  "https://en.wikipedia.org/wiki/Robert_Cecil_Martin",
  (requestErr, response, body) => {
    if (requestErr) {
      console.error(requestErr);
    } else {
      writeFile("article.html", body, writeErr => {
        if (writeErr) {
          console.error(writeErr);
        } else {
          console.log("File written");
        }
      });
    }
  }
);

Good:

import { get } from "request-promise";
import { writeFile } from "fs-extra";
get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin")
  .then(body => {
    return writeFile("article.html", body);
  })
  .then(() => {
    console.log("File written");
  })
  .catch(err => {
    console.error(err);
  });

Async/Await are even cleaner than Promises

Bad:

import { get } from "request-promise";
import { writeFile } from "fs-extra";
get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin")
  .then(body => {
    return writeFile("article.html", body);
  })
  .then(() => {
    console.log("File written");
  })
  .catch(err => {
    console.error(err);
  });

Good:

import { get } from "request-promise";
import { writeFile } from "fs-extra";
async function getCleanCodeArticle() {
  try {
    const body = await get(
      "https://en.wikipedia.org/wiki/Robert_Cecil_Martin"
    );
    await writeFile("article.html", body);
    console.log("File written");
  } catch (err) {
    console.error(err);
  }
}
getCleanCodeArticle()

3、错误捕获

Bad:

try {
  functionThatMightThrow();
} catch (error) {
  console.log(error);
}

Good:

try {
  functionThatMightThrow();
} catch (error) {
  // One option (more noisy than console.log):
  console.error(error);
  // Another option:
  notifyUserOfError(error);
  // Another option:
  reportErrorToService(error);
  // OR do all three!
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值