成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯] 如何寫(xiě)出漂亮的 JavaScript 代碼

amuqiao / 553人閱讀

摘要:如何提高代碼的可讀性復(fù)用性擴(kuò)展性。嚴(yán)格遵守這條規(guī)則會(huì)讓你的代碼可讀性更好,也更容易重構(gòu)。如果違反這個(gè)規(guī)則,那么代碼會(huì)很難被測(cè)試或者重用。它讓你的代碼簡(jiǎn)潔優(yōu)雅。

原文:https://github.com/ryanmcderm...  
說(shuō)明:本文翻譯自 github 上的一個(gè)項(xiàng)目,非全文搬運(yùn),只取部分精華。

如何提高代碼的可讀性、復(fù)用性、擴(kuò)展性。我們將從以下四個(gè)方面討論:

變量

函數(shù)

異步

一、變量 用有意義且常用的單詞命名
// Bad:
const yyyymmdstr = moment().format("YYYY/MM/DD");
// Good:
const currentDate = moment().format("YYYY/MM/DD");
保持統(tǒng)一

對(duì)同一類型的變量使用相同的命名保持統(tǒng)一:

// Bad:
getUserInfo();
getClientData();
getCustomerRecord();
// Good:
getUser()
每個(gè)常量(全大寫(xiě))都該命名

可以用 ESLint 檢測(cè)代碼中未命名的常量。

// Bad:
// 其他人知道 86400000 的意思嗎?
setTimeout( blastOff, 86400000 );
// Good:
const MILLISECOND_IN_A_DAY = 86400000;
setTimeout( blastOff, MILLISECOND_IN_A_DAY );
避免無(wú)意義的命名

既然創(chuàng)建了一個(gè) car 對(duì)象,就沒(méi)有必要把它的顏色命名為 carColor。

// Bad:
const car = {
    carMake: "Honda",
    carModel: "Accord",
    carColor: "Blue"
};
function paintCar( car ) {
    car.carColor = "Red";
}
// Good:
const car = {
    make: "Honda",
    model: "Accord",
    color: "Blue"
};
function paintCar( car ) {
    car.color = "Red";
}
傳參使用默認(rèn)值
// Bad:
function createMicrobrewery( name ) {
    const breweryName = name || "Hipster Brew Co.";
    // ...
}
// Good:
function createMicrobrewery( name = "Hipster Brew Co." ) {
    // ...
}
二、函數(shù) 函數(shù)參數(shù)( 最好 2 個(gè)或更少 )

如果參數(shù)超過(guò)兩個(gè),建議使用 ES6 的解構(gòu)語(yǔ)法,不用考慮參數(shù)的順序。

// Bad:
function createMenu( title, body, buttonText, cancellable ) {
    // ...
}
// Good:
function createMenu( { title, body, buttonText, cancellable } ) {
    // ...
}
createMenu({
    title: "Foo",
    body: "Bar",
    buttonText: "Baz",
    cancellable: true
});
一個(gè)方法只做一件事情

這是一條在軟件工程領(lǐng)域流傳久遠(yuǎn)的規(guī)則。嚴(yán)格遵守這條規(guī)則會(huì)讓你的代碼可讀性更好,也更容易重構(gòu)。如果違反這個(gè)規(guī)則,那么代碼會(huì)很難被測(cè)試或者重用。

// 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();
}
函數(shù)名上體現(xiàn)它的作用
// Bad:
function addToDate( date, month ) {
    // ...
}
const date = new Date();
// 很難知道是把什么加到日期中
addToDate( date, 1 );
// Good:
function addMonthToDate( month, date ) {
    // ...
}
const date = new Date();
addMonthToDate( 1, date );
刪除重復(fù)代碼,合并相似函數(shù)

很多時(shí)候雖然是同一個(gè)功能,但由于一兩個(gè)不同點(diǎn),讓你不得不寫(xiě)兩個(gè)幾乎相同的函數(shù)。

// 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 "develop":
        data.githubLink = employee.getGithubLink();
        break
      case "manager":
        data.portfolio = employee.getMBAProjects();
        break
    }
    render(data);
  })
}
使用 Object.assign 設(shè)置默認(rèn)屬性
// 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",
  // 不包含 body
  buttonText: "Send",
  cancellable: true
};
function createMenu(config) {
  config = Object.assign({
    title: "Foo",
    body: "Bar",
    buttonText: "Baz",
    cancellable: true
  }, config);
  // config : {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}
createMenu(menuConfig);
盡量不要寫(xiě)全局方法

在 JavaScript 中,永遠(yuǎn)不要污染全局,會(huì)在生產(chǎn)環(huán)境中產(chǎn)生難以預(yù)料的 bug。舉個(gè)例子,比如你在 Array.prototype 上新增一個(gè) diff 方法來(lái)判斷兩個(gè)數(shù)組的不同。而你同事也打算做類似的事情,不過(guò)他的 diff 方法是用來(lái)判斷兩個(gè)數(shù)組首位元素的不同。很明顯你們方法會(huì)產(chǎn)生沖突,遇到這類問(wèn)題我們可以用 ES2015/ES6 的語(yǔ)法來(lái)對(duì) Array 進(jìn)行擴(kuò)展。

// Bad:
Array.prototype.diff = function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  return this.filter(elem => !hash.has(elem));
};
// Good:
class SuperArray extends Array {
  diff(comparisonArray) {
    const hash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));        
  }
}
盡量別用“非”條件句
// Bad:
function isDOMNodeNotPresent(node) {
  // ...
}
if (!isDOMNodeNotPresent(node)) {
  // ...
}
// Good:
function isDOMNodePresent(node) {
  // ...
}
if (isDOMNodePresent(node)) {
  // ...
}
不要過(guò)度優(yōu)化

現(xiàn)代瀏覽器已經(jīng)在底層做了很多優(yōu)化,過(guò)去的很多優(yōu)化方案都是無(wú)效的,會(huì)浪費(fèi)你的時(shí)間。

// Bad:
// 現(xiàn)代瀏覽器已對(duì)此( 緩存 list.length )做了優(yōu)化。
for (let i = 0, len = list.length; i < len; i++) {
  // ...
}
// Good:
for (let i = 0; i < list.length; i++) {
  // ...
}
刪除棄用代碼

這里沒(méi)有實(shí)例代碼,刪除就對(duì)了

三、類 使用 ES6 的 class

在 ES6 之前,沒(méi)有類的語(yǔ)法,只能用構(gòu)造函數(shù)的方式模擬類,可讀性非常差。

// Good:
// 動(dòng)物
class Animal {
  constructor(age) {
    this.age = age
  };
  move() {};
}
// 哺乳動(dòng)物
class Mammal extends Animal{
  constructor(age, furColor) {
    super(age);
    this.furColor = furColor;
  };
  liveBirth() {};
}
// 人類
class Human extends Mammal{
  constructor(age, furColor, languageSpoken) {
    super(age, furColor);
    this.languageSpoken = languageSpoken;
  };
  speak() {};
}
使用鏈?zhǔn)秸{(diào)用

這種模式相當(dāng)有用,可以在很多庫(kù)中都有使用。它讓你的代碼簡(jiǎn)潔優(yōu)雅。

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);
  }
}
// Bad:
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();
四、異步 使用 promise 或者 Async/Await 代替回調(diào)
// Bad:
get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin", (requestErr, response) => {
  if (requestErr) {
    console.error(requestErr);
  } else {
    writeFile("article.html", response.body, (writeErr) => {
      if (writeErr) {
        console.error(writeErr);
      } else {
        console.log("File written");
      }
    });
  }
});
// Good:
get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin")
  .then((response) => {
    return writeFile("article.html", response);
  })
  .then(() => {
    console.log("File written");
  })
  .catch((err) => {
    console.error(err);
  });

// perfect:
async function getCleanCodeArticle() {
  try {
    const response = await get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin");
    await writeFile("article.html", response);
    console.log("File written");
  } catch(err) {
    console.error(err);
  }
}
后記

如果你想進(jìn)【大前端交流群】,關(guān)注公眾號(hào)點(diǎn)擊“交流加群”添加機(jī)器人自動(dòng)拉你入群。關(guān)注我第一時(shí)間接收最新干貨。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105035.html

相關(guān)文章

  • Top 15 - Material Design框架和類庫(kù)()

    摘要:這是一個(gè)用于構(gòu)建響應(yīng)式應(yīng)用和網(wǎng)站的前端框架。是基于設(shè)計(jì)的一套豐富的組件。這是一個(gè)對(duì)混合式手機(jī)應(yīng)用框架的擴(kuò)展庫(kù)。到目前為止它僅大小,而且不依賴于任何第三方的插件,它可以很輕量的被用來(lái)創(chuàng)建和應(yīng)用。 _Material design_是Google開(kāi)發(fā)的,目的是為了統(tǒng)一公司的web端和手機(jī)端的產(chǎn)品風(fēng)格。它是基于很多的原則,比如像合適的動(dòng)畫(huà),響應(yīng)式,以及顏色和陰影的使用。完整的指南詳情請(qǐng)看這里...

    Cristic 評(píng)論0 收藏0
  • Top 15 - Material Design框架和類庫(kù)()

    摘要:這是一個(gè)用于構(gòu)建響應(yīng)式應(yīng)用和網(wǎng)站的前端框架。是基于設(shè)計(jì)的一套豐富的組件。這是一個(gè)對(duì)混合式手機(jī)應(yīng)用框架的擴(kuò)展庫(kù)。到目前為止它僅大小,而且不依賴于任何第三方的插件,它可以很輕量的被用來(lái)創(chuàng)建和應(yīng)用。 _Material design_是Google開(kāi)發(fā)的,目的是為了統(tǒng)一公司的web端和手機(jī)端的產(chǎn)品風(fēng)格。它是基于很多的原則,比如像合適的動(dòng)畫(huà),響應(yīng)式,以及顏色和陰影的使用。完整的指南詳情請(qǐng)看這里...

    phpmatt 評(píng)論0 收藏0
  • []148個(gè)資源讓你成為CSS專家

    摘要:層疊樣式表二修訂版這是對(duì)作出的官方說(shuō)明。速查表兩份表來(lái)自一份關(guān)于基礎(chǔ)特性,一份關(guān)于布局。核心第一篇一份來(lái)自的基礎(chǔ)參考指南簡(jiǎn)寫(xiě)速查表簡(jiǎn)寫(xiě)形式參考書(shū)使用層疊樣式表基礎(chǔ)指南,包含使用的好處介紹個(gè)方法快速寫(xiě)成高質(zhì)量的寫(xiě)出高效的一些提示。 迄今為止,我已經(jīng)收集了100多個(gè)精通CSS的資源,它們能讓你更好地掌握CSS技巧,使你的布局設(shè)計(jì)脫穎而出。 CSS3 資源 20個(gè)學(xué)習(xí)CSS3的有用資源 C...

    impig33 評(píng)論0 收藏0
  • 2017-08-10 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選譯用搭建探索生命周期中的匿名遞歸瀏覽器端機(jī)器智能框架深入理解筆記和屬性中文上海線下活動(dòng)前端工程化架構(gòu)實(shí)踐滬江技術(shù)沙龍掘金周二放送追加視頻知乎專欄第期聊一聊前端自動(dòng)化測(cè)試上雙關(guān)語(yǔ)來(lái)自前端的小段子,你看得懂嗎眾成翻 2017-08-10 前端日?qǐng)?bào) 精選 [譯] 用 Node.js 搭建 API Gateway探索 Service Worker 「生命周期」JavaScript ...

    wupengyu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

amuqiao

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<