javascript
JavaScript: 代码简洁之道
一、變量
1、用有意義且常用的單詞命名變量
Bad: const yyyymmdstr = moment().format('YYYY/MM/DD');Good: const currentDate = moment().format('YYYY/MM/DD');
2、保持統一
可能同一個項目對于獲取用戶信息,會有三個不一樣的命名,應該保持統一。
Bad:getUserInfo();getClientData();getCustomerRecord();Good:getUser()?
3、每個常量都該命名
可以用?buddy.js?或者?ESLint?檢測代碼中未命名的常量。
Bad: // 三個月之后你還能知道 86400000 是什么嗎? setTimeout(blastOff, 86400000);Good: const MILLISECOND_IN_A_DAY = 86400000; setTimeout(blastOff, MILLISECOND_IN_A_DAY);4、可描述
通過一個變量生成了一個新變量,也需要為這個新變量命名,也就是說每個變量當你看到他第一眼你就知道他是干什么的。
Bad: const ADDRESS = 'One Infinite Loop, Cupertino 95014'; const CITY_ZIP_CODE_REGEX = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; saveCityZipCode(ADDRESS.match(CITY_ZIP_CODE_REGEX)[1],ADDRESS.match(CITY_ZIP_CODE_REGEX)[2]);Good: const ADDRESS = 'One Infinite Loop, Cupertino 95014'; const CITY_ZIP_CODE_REGEX = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; const [, city, zipCode] = ADDRESS.match(CITY_ZIP_CODE_REGEX) || []; saveCityZipCode(city, zipCode);5、直接了當
bad
const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((l) => {doStuff();doSomeOtherStuff();// ...// ...// ...// 需要看其他代碼才能確定 'l' 是干什么的。 dispatch(l); });good
const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((location) => {doStuff();doSomeOtherStuff();// ...// ...// ... dispatch(location); });4、避免無意義的前綴
如果創建了一個對象 car,就沒有必要把它的顏色命名為 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'; }5、使用默認值
Bad: function createMicrobrewery(name) {const breweryName = name || 'Hipster Brew Co.';// ... }Good: function createMicrobrewery(name = 'Hipster Brew Co.') {// ... }二、函數?
1、參數越少越好
如果參數超過兩個,使用 ES2015/ES6 的解構語法,不用考慮參數的順序。
Bad: function createMenu(title, body, buttonText, cancellable) {// ... }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();// 很難知道是把什么加到日期中 addToDate(date, 1);Good: function addMonthToDate(month, date) {// ... }const date = new Date(); addMonthToDate(1, date);4、刪除重復代碼
很多時候雖然是同一個功能,但由于一兩個不同點,讓你不得不寫兩個幾乎相同的函數。
要想優化重復代碼需要有較強的抽象能力,錯誤的抽象還不如重復代碼。所以在抽象過程中必須要遵循 SOLID 原則(SOLID 是什么?稍后會詳細介紹)。
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();breakcase 'manager':data.portfolio = employee.getMBAProjects();break}render(data);}) }5、對象設置默認屬性
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' key 缺失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);
6、不要傳 flag 參數
通過 flag 的 true 或 false,來判斷執行邏輯,違反了一個函數干一件事的原則。
Bad: function createFile(name, temp) {if (temp) {fs.create(`./temp/${name}`);} else {fs.create(name);} }Good: function createFile(name) {fs.create(name); } function createFileTemplate(name) {createFile(`./temp/${name}`) }?7、避免副作用(第一部分)
函數接收一個值返回一個新值,除此之外的行為我們都稱之為副作用,比如修改全局變量、對文件進行 IO 操作等。
當函數確實需要副作用時,比如對文件進行 IO 操作時,請不要用多個函數/類進行文件操作,有且僅用一個函數/類來處理。也就是說副作用需要在唯一的地方處理。
副作用的三大天坑:隨意修改可變數據類型、隨意分享沒有數據結構的狀態、沒有在統一地方處理副作用。
Bad: // 全局變量被一個函數引用 // 現在這個變量從字符串變成了數組,如果有其他的函數引用,會發生無法預見的錯誤。 var name = 'Ryan McDermott';function splitIntoFirstAndLastName() {name = name.split(' '); }splitIntoFirstAndLastName();console.log(name); // ['Ryan', 'McDermott']; Good: var name = 'Ryan McDermott'; var newName = splitIntoFirstAndLastName(name)function splitIntoFirstAndLastName(name) {return name.split(' '); }console.log(name); // 'Ryan McDermott'; console.log(newName); // ['Ryan', 'McDermott'];8、避免副作用(第二部分)
在 JavaScript 中,基本類型通過賦值傳遞,對象和數組通過引用傳遞。以引用傳遞為例:
假如我們寫一個購物車,通過 addItemToCart() 方法添加商品到購物車,修改 購物車數組。此時調用 purchase() 方法購買,由于引用傳遞,獲取的 購物車數組 正好是最新的數據。
看起來沒問題對不對?
如果當用戶點擊購買時,網絡出現故障, purchase() 方法一直在重復調用,與此同時用戶又添加了新的商品,這時網絡又恢復了。那么 purchase() 方法獲取到 購物車數組 就是錯誤的。
為了避免這種問題,我們需要在每次新增商品時,克隆 購物車數組 并返回新的數組。
Bad: const addItemToCart = (cart, item) => {cart.push({ item, date: Date.now() }); };Good: const addItemToCart = (cart, item) => {return [...cart, {item, date: Date.now()}] };?
轉載于:https://www.cnblogs.com/Nyan-Workflow-FC/p/10464431.html
總結
以上是生活随笔為你收集整理的JavaScript: 代码简洁之道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小鼠稀释成瘤实验统计方法
- 下一篇: java初始化