Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 的简洁之道 #56

Open
husky-dot opened this issue Jun 10, 2019 · 0 comments
Open

JavaScript 的简洁之道 #56

husky-dot opened this issue Jun 10, 2019 · 0 comments

Comments

@husky-dot
Copy link
Owner

简介

如果你关注代码本身和代码的编写方式,而不是只关心它是否能工作,那么你写代码是有一定的水准。专业开发人员将为未来的自己和“其他人”编写代码,而不仅仅只编写当前能工作就行的代码。

在此基础上,简洁代码可以定义为自解释的、易于人理解的、易于更改或扩展的代码。

以下列表一些好编写方式,仅供参考,当然,如果你有更好的方式,欢迎留言。

1. 强类型检查

===代替 ==

// 如果处理不当,它会极大地影响程序逻辑。这就像,你想向左走,但由于某种原因,你向右走
0 == false // true
0 === false // false
2 == "2" // true
2 === "2" // false

// 例子
const value = "500";
if (value === 500) {
  console.log(value);
  // 条件不成立,不会进入
}

if (value === "500") {
  console.log(value);
  // 条件成立,会进入
}

2.变量

用知名其意的方式为变量命名,通过这种方式,当一个人看到它们时,易于搜索和理解。

不好的方式:

let daysSLV = 10;
let y = new Date().getFullYear();

let ok;
if (user.age > 30) {
  ok = true;
}

好的方式:

const MAX_AGE = 30;
let daysSinceLastVisit = 10;
let currentYear = new Date().getFullYear();

...

const isUserOlderThanAllowed = user.age > MAX_AGE;

不要在变量名中添加额外的不需要的单词。

不好的方式:

let nameValue;
let theProduct;

好的方式:

let name;
let product;

不要简写变量上下文。

不好的方式:

const users = ["John", "Marco", "Peter"];
users.forEach(u => {
  doSomething();
  doSomethingElse();
  // ...
  // ...
  // ...
  // ...
  // 当上面代码很多的时候 ,这 `u` 是什么鬼
  register(u);
});

好的方式:

const users = ["John", "Marco", "Peter"];
users.forEach(user => {
  doSomething();
  doSomethingElse();
  // ...
  // ...
  // ...
  // ...
  register(user);
});

不要添加不必要的上下文。

不好的方式:

const user = {
  userName: "John",
  userSurname: "Doe",
  userAge: "28"
};

...

user.userName;

好的方式:

const user = {
  name: "John",
  surname: "Doe",
  age: "28"
};

...

user.name;

3. 函数

使用长而具有描述性的名称。 考虑到函数表示某种行为,函数名称应该是动词或短​​语,用以说明其背后的意图以及参数的意图。 函数的名字应该说明他们做了什么。

不好的方式:

function notif(user) {
  // implementation
}

好的方式:

function notifyUser(emailAddress) {
  // implementation
}

避免使用大量参数。 理想情况下,函数应该指定两个或更少的参数。 参数越少,测试函数就越容易,参数多的情况可以使用对象。

不好的方式:

function getUsers(fields, fromDate, toDate) {
  // implementation
}

好的方式:

function getUsers({ fields, fromDate, toDate }) {
  // implementation
}

getUsers({
  fields: ['name', 'surname', 'email'],
  fromDate: '2019-01-01',
  toDate: '2019-01-18'
});

使用默认参数替代 || 操作

不好的方式:

function createShape(type) {
  const shapeType = type || "cube";
  // ...
}

好的方式:

function createShape(type = "cube") {
  // ...
}

一个函数应该只做一件事,不要在一个函数中执行多个操作。

不好的方式:

function notifyUsers(users) {
  users.forEach(user => {
    const userRecord = database.lookup(user);
    if (userRecord.isVerified()) {
      notify(user);
    }
  });
}

好的方式:

function notifyVerifiedUsers(users) {
  users.filter(isUserVerified).forEach(notify);
}

function isUserVerified(user) {
  const userRecord = database.lookup(user);
  return userRecord.isVerified();
}

使用Object.assign设置对象默认值。

不好的方式:

const shapeConfig = {
  type: "cube",
  width: 200,
  height: null
};

function createShape(config) {
  config.type = config.type || "cube";
  config.width = config.width || 250;
  config.height = config.height|| 250;
}


createShape(shapeConfig);

好的方式:

const shapeConfig = {
  type: "cube",
  width: 200
  // Exclude the 'height' key
};

function createShape(config) {
  config = Object.assign(
    {
      type: "cube",
      width: 250,
      height: 250
    },
    config
  );

  ...
}

createShape(shapeConfig);

不要使用标志作为参数,因为它们告诉函数做的比它应该做的多。

不好的方式:

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

好的方式:

function createFile(name) {
  fs.create(name);
}

function createPublicFile(name) {
  createFile(`./public/${name}`);
}

不要污染全局变量。 如果需要扩展现有对象,请使用ES类和继承,而不是在原生对象的原型链上创建函数。

不好的方式:

Array.prototype.myFunc = function myFunc() {
  // implementation
};

好的方式:

class SuperArray extends Array {
  myFunc() {
    // implementation
  }
}

4. 条件

避免使用反面条件。

不好的方式:

function isUserNotBlocked(user) {
  // implementation
}

if (!isUserNotBlocked(user)) {
  // implementation
}

好的方式:

function isUserBlocked(user) {
  // implementation
}

if (isUserBlocked(user)) {
  // implementation
}

使用条件简写。这可能微不足道,但值得一提。仅对布尔值使用此方法,并且如果你确信该值不会是undefinednull的,则使用此方法。

不好的方式:

if (isValid === true) {
  // do something...
}

if (isValid === false) {
  // do something...
}

好的方式:

if (isValid) {
  // do something...
}

if (!isValid) {
  // do something...
}

尽可能避免条件句,而是使用多态性和继承。

不好的方式:

class Car {
  // ...
  getMaximumSpeed() {
    switch (this.type) {
      case "Ford":
        return this.someFactor() + this.anotherFactor();
      case "Mazda":
        return this.someFactor();
      case "McLaren":
        return this.someFactor() - this.anotherFactor();
    }
  }
}

好的方式:

class Car {
  // ...
}

class Ford extends Car {
  // ...
  getMaximumSpeed() {
    return this.someFactor() + this.anotherFactor();
  }
}

class Mazda extends Car {
  // ...
  getMaximumSpeed() {
    return this.someFactor();
  }
}

class McLaren extends Car {
  // ...
  getMaximumSpeed() {
    return this.someFactor() - this.anotherFactor();
  }
}

5. 类

class 是JavaScript中新的语法糖。一切工作就像以前的原型,只是它现在看起来不同,你应该更喜欢他们比ES5普通功能。

不好的方式:

const Person = function(name) {
  if (!(this instanceof Person)) {
    throw new Error("Instantiate Person with `new` keyword");
  }

  this.name = name;
};

Person.prototype.sayHello = function sayHello() { /**/ };

const Student = function(name, school) {
  if (!(this instanceof Student)) {
    throw new Error("Instantiate Student with `new` keyword");
  }

  Person.call(this, name);
  this.school = school;
};

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.printSchoolName = function printSchoolName() { /**/ };

好的方式:

class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    /* ... */
  }
}

class Student extends Person {
  constructor(name, school) {
    super(name);
    this.school = school;
  }

  printSchoolName() {
    /* ... */
  }
}

使用链接。许多库(如jQuery和Lodash)都使用这种模式。在类中,只需在每个函数的末尾返回this就可以将更多的该类方法链接到它上。

不好的方式:

class Person {
  constructor(name) {
    this.name = name;
  }

  setSurname(surname) {
    this.surname = surname;
  }

  setAge(age) {
    this.age = age;
  }

  save() {
    console.log(this.name, this.surname, this.age);
  }
}

const person = new Person("John");
person.setSurname("Doe");
person.setAge(29);
person.save();

好的方式:

class Person {
  constructor(name) {
    this.name = name;
  }

  setSurname(surname) {
    this.surname = surname;
    // Return this for chaining
    return this;
  }

  setAge(age) {
    this.age = age;
    // Return this for chaining
    return this;
  }

  save() {
    console.log(this.name, this.surname, this.age);
    // Return this for chaining
    return this;
  }
}

const person = new Person("John")
    .setSurname("Doe")
    .setAge(29)
    .save();

总结

这只是改进代码的一小部分。一般生活入,这里所说的原则是人们通常不遵守的原则。他们尝试着去做,但出于各种原因,就没有坚持下去。也许在项目开始时,代码是简洁的,但是当要在截止日期前完成时,这些原则常常被忽略,并被转移到“TODO”或“REFACTOR”部分。在这一点上,你的客户更希望您在最后期限之前完成任务,而不是编写简洁的代码。

** 原文:https://devinduct.com/blogpost/22/javascript-clean-code-best-practices **

交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant