最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
當前位置:
首頁 > 網站開發 > JavaScript >
  • JavaScript教程之Clean Code之JavaScript代碼示例

  • 2019-06-17 18:30 來源:未知

譯者按: 簡潔的代碼可以避免寫出過多的BUG。

  • 原文: JavaScript Clean Code - Best Practices
  • 譯者: Fundebug

本文采用意譯,版權歸原作者所有

引文

作為一個開發者,如果你關心代碼質量,除了需要認真測試代碼能否正確執行以外,還要注重代碼的整潔(clean code)。一個專業的開發者會從將來自己或則他人方便維護的角度考慮如何寫代碼,而不僅僅是機器能夠讀懂。你寫的任何代碼有很大幾率會被再次重構,希望未來重構代碼的那個人不會覺得這是一場災難。

代碼的簡潔之道可以被理解為:代碼自我解釋(且注釋少),開發者友好(易于理解,修改和擴展)。

想想之前閱讀別人的代碼的時候,說過多少次下面的話?

"WTF is that?"

"WTF did you do here?"

"WTF is this for?"

下面這張圖很形象地描述了這個情況:

img

《Clean Code》的作者Robert C. Martin (Uncle Bob) 說過這樣的話.

雖然爛代碼可以運行,但是它不夠整潔,它會把整個開發團隊給整跪了

本文主要講 JavaScript 代碼的整潔之道。

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

在某些環境下,不用添加冗余的單詞來組合命名。比如一個對象叫user,那么其中的一個名字的屬性直接用name,不需要再使用username了。

壞的命名方式:

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
}

避免使用過多參數。最好一個函數只有 2 個甚至更少的參數。參數越少,越容易做測試。

壞的使用方式:

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

使用Objecg.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.width || 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);

不要使用 true/false 的標簽(flag),因為它實際上讓函數做了超出它本身的事情。

壞的寫法:

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

好的代碼風格可以避免不小心寫出有BUG的代碼,以防萬一,推薦使用Fundebug做線上實時BUG監控!

4. 判斷條件

避免使用否定的條件。

壞的寫法:

function isUserNotBlocked(user) {
    // implementation
}

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

好的寫法:

function isUserBlocked(user) {
    // implementation
}

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

使用簡短的條件。這個要求看上去簡單,但是值得提醒。

壞的寫法:

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

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

好的寫法:

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

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

如果你很確定它的值不是undefined或則null,我建議你這么做。

盡量避免使用判斷條件,推薦說那個多態(polymorphism)或則繼承。

壞的寫法:

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. ES 類

類是 JavaScript 新推出的語法糖。建議使用類而不是用老式的直接定義函數的寫法。

壞的寫法:

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

6. 其它

總的來說,你不能寫重復代碼,不能留下一堆不再使用的函數,永遠不會執行的代碼(死代碼)。

在很多情況下,你可能搞出重復代碼。比如你要實現兩個略微不同的功能,他們有很多相通的地方,但是由于項目截止時間快到了,你不得不快速復制黏貼再稍微修改修改來實現。

對于死代碼,最好的做法就是你決定不再使用它的那一刻就把它刪掉。時間過去太久,你甚至會忘記自己當初為什么定義它。下面這幅圖很形象地描述了這個情況:

版權聲明

轉載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2019/06/11/javascript-clean-code/

pk10赛车冠军技巧
最稳的pk10计划iphone 北京pk10计划手机软件 北京pk10数字的规律 超神手机版pk10软件 pk10北京赛车9码技巧 pk10四期倍投计划表 pk10极速赛车论坛 北京赛车冠军怎样选5码 北京赛车系统下载安装 pk10教程视频 北京pk10选号公式 北京赛车pk10赚钱技巧 北京赛车怎么提升概率 pk10技巧北京快三 北京pk10大小计划
用友软件实施赚钱吗 欢乐捕鱼人最新破解版 十一运夺金预测 云南11选5胆拖参考表 男人多运动 赚钱更多 69 5开怎样赚钱 星空棋牌app 快乐双彩走势图大 瑞波币交易网