91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何寫出高質量的javascript代碼

發布時間:2020-06-15 15:56:24 來源:億速云 閱讀:155 作者:元一 欄目:web開發

目的

在我們平時的工作開發中,大多數都是大人協同開發的公共項目;在我們平時開發中代碼codeing的時候我們考慮代碼的可讀性、復用性和擴展性。

干凈的代碼,既在質量上較為可靠,也為后期維護、升級奠定了良好基礎。

我們從以下幾個方面進行探討:

變量

1、變量命名

一般我們在定義變量是要使用有意義的詞匯命令,要做到見面知義

//bad code
const yyyymmdstr = moment().format('YYYY/MM/DD');
//better code
const currentDate = moment().format('YYYY/MM/DD');

2、可描述

通過一個變量生成了一個新變量,也需要為這個新變量命名,也就是說每個變量當你看到他第一眼你就知道他是干什么的。

//bad code
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]);

//better code
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);

3、形參命名

在for、forEach、map的循環中我們在命名時要直接

//bad code
const locations = ['Austin', 'New York', 'San Francisco'];
locations.map((l) => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  // 需要看其他代碼才能確定 'l' 是干什么的。
  dispatch(l);
});

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

4、避免無意義的前綴

例如我們只創建一個對象是,沒有必要再把每個對象的屬性上再加上對象名

//bad code
const car = {
  carMake: 'Honda',
  carModel: 'Accord',
  carColor: 'Blue'
};

function paintCar(car) {
  car.carColor = 'Red';
}

//better code
const car = {
  make: 'Honda',
  model: 'Accord',
  color: 'Blue'
};

function paintCar(car) {
  car.color = 'Red';
}

5、默認值

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

//better code
function createMicrobrewery(name = 'Hipster Brew Co.') {
  // ...
}

函數

1、參數

一般參數多的話要使用ES6的解構傳參的方式

//bad code
function createMenu(title, body, buttonText, cancellable) {
  // ...
}

//better code
function createMenu({ title, body, buttonText, cancellable }) {
  // ...
}

//better code
createMenu({
  title: 'Foo',
  body: 'Bar',
  buttonText: 'Baz',
  cancellable: true
});

2、單一化處理

一個方法里面最好只做一件事,不要過多的處理,這樣代碼的可讀性非常高

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

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

3、對象設置默認屬性

//bad code
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);
//better code
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);

4、避免副作用

函數接收一個值返回一個新值,除此之外的行為我們都稱之為副作用,比如修改全局變量、對文件進行 IO 操作等。

當函數確實需要副作用時,比如對文件進行 IO 操作時,請不要用多個函數/類進行文件操作,有且僅用一個函數/類來處理。也就是說副作用需要在唯一的地方處理。

副作用的三大天坑:隨意修改可變數據類型、隨意分享沒有數據結構的狀態、沒有在統一地方處理副作用。

//bad code
// 全局變量被一個函數引用
// 現在這個變量從字符串變成了數組,如果有其他的函數引用,會發生無法預見的錯誤。
var name = 'Ryan McDermott';
function splitIntoFirstAndLastName() {
  name = name.split(' ');
}
splitIntoFirstAndLastName();
console.log(name); // ['Ryan', 'McDermott'];
//better code
var name = 'Ryan McDermott';
var newName = splitIntoFirstAndLastName(name)
function splitIntoFirstAndLastName(name) {
  return name.split(' ');
}
console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];

在 JavaScript 中,基本類型通過賦值傳遞,對象和數組通過引用傳遞。以引用傳遞為例:

假如我們寫一個購物車,通過 addItemToCart()方法添加商品到購物車,修改 購物車數組。此時調用 purchase()方法購買,由于引用傳遞,獲取的 購物車數組正好是最新的數據。

看起來沒問題對不對?

如果當用戶點擊購買時,網絡出現故障, purchase()方法一直在重復調用,與此同時用戶又添加了新的商品,這時網絡又恢復了。那么 purchase()方法獲取到 購物車數組就是錯誤的。

為了避免這種問題,我們需要在每次新增商品時,克隆 購物車數組并返回新的數組。

//bad code
const addItemToCart = (cart, item) => {
  cart.push({ item, date: Date.now() });
};

//better code
const addItemToCart = (cart, item) => {
  return [...cart, {item, date: Date.now()}]
};

5、全局方法

在 JavaScript 中,永遠不要污染全局,會在生產環境中產生難以預料的 bug。舉個例子,比如你在 Array.prototype上新增一個 diff方法來判斷兩個數組的不同。而你同事也打算做類似的事情,不過他的 diff方法是用來判斷兩個數組首位元素的不同。很明顯你們方法會產生沖突,遇到這類問題我們可以用 ES2015/ES6 的語法來對 Array進行擴展。

//bad code
Array.prototype.diff = function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  return this.filter(elem => !hash.has(elem));
};

//better code
class SuperArray extends Array {
  diff(comparisonArray) {
    const hash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));        
  }
}

6、避免類型檢查

JavaScript 是無類型的,意味著你可以傳任意類型參數,這種自由度很容易讓人困擾,不自覺的就會去檢查類型。仔細想想是你真的需要檢查類型還是你的 API 設計有問題?

//bad code
function travelToTexas(vehicle) {
  if (vehicle instanceof Bicycle) {
    vehicle.pedal(this.currentLocation, new Location('texas'));
  } else if (vehicle instanceof Car) {
    vehicle.drive(this.currentLocation, new Location('texas'));
  }
}

//better code
function travelToTexas(vehicle) {
  vehicle.move(this.currentLocation, new Location('texas'));
}

如果你需要做靜態類型檢查,比如字符串、整數等,推薦使用 TypeScript,不然你的代碼會變得又臭又長。

//bad code
function combine(val1, val2) {
  if (typeof val1 === 'number' && typeof val2 === 'number' ||
      typeof val1 === 'string' && typeof val2 === 'string') {
    return val1 + val2;
  }
  throw new Error('Must be of type String or Number');
}
//better code
function combine(val1, val2) {
  return val1 + val2;
}

復雜條件判斷

我們編寫js代碼時經常遇到復雜邏輯判斷的情況,通常大家可以用if/else或者switch來實現多個條件判斷,但這樣會有個問題,隨著邏輯復雜度的增加,代碼中的if/else/switch會變得越來越臃腫,越來越看不懂,那么如何更優雅的寫判斷邏輯

1、if/else

點擊列表按鈕事件

/**
 * 按鈕點擊事件
 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消
 */
const onButtonClick = (status)=>{
  if(status == 1){
    sendLog('processing')
    jumpTo('IndexPage')
  }else if(status == 2){
    sendLog('fail')
    jumpTo('FailPage')
  }else if(status == 3){
    sendLog('fail')
    jumpTo('FailPage')
  }else if(status == 4){
    sendLog('success')
    jumpTo('SuccessPage')
  }else if(status == 5){
    sendLog('cancel')
    jumpTo('CancelPage')
  }else {
    sendLog('other')
    jumpTo('Index')
  }
}

從上面我們可以看到的是通過不同的狀態來做不同的事情,代碼看起來非常不好看,大家可以很輕易的提出這段代碼的改寫方案,switch出場:

2、switch/case

/**
 * 按鈕點擊事件
 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消
 */
const onButtonClick = (status)=>{
  switch (status){
    case 1:
      sendLog('processing')
      jumpTo('IndexPage')
      break
    case 2:
    case 3:
      sendLog('fail')
      jumpTo('FailPage')
      break  
    case 4:
      sendLog('success')
      jumpTo('SuccessPage')
      break
    case 5:
      sendLog('cancel')
      jumpTo('CancelPage')
      break
    default:
      sendLog('other')
      jumpTo('Index')
      break
  }
}

這樣看起來比if/else清晰多了,細心的同學也發現了小技巧,case 2和case 3邏輯一樣的時候,可以省去執行語句和break,則case 2的情況自動執行case 3的邏輯。

3、存放到Object

將判斷條件作為對象的屬性名,將處理邏輯作為對象的屬性值,在按鈕點擊的時候,通過對象屬性查找的方式來進行邏輯判斷,這種寫法特別適合一元條件判斷的情況。

const actions = {
  '1': ['processing','IndexPage'],
  '2': ['fail','FailPage'],
  '3': ['fail','FailPage'],
  '4': ['success','SuccessPage'],
  '5': ['cancel','CancelPage'],
  'default': ['other','Index'],
}
/**
 * 按鈕點擊事件
 * @param {number} status 活動狀態:1開團進行中 2開團失敗 3 商品售罄 4 開團成功 5 系統取消
 */
const onButtonClick = (status)=>{
  let action = actions[status] || actions['default'],
      logName = action[0],
      pageName = action[1]
  sendLog(logName)
  jumpTo(pageName)
}

4、存放到Map

const actions = new Map([
  [1, ['processing','IndexPage']],
  [2, ['fail','FailPage']],
  [3, ['fail','FailPage']],
  [4, ['success','SuccessPage']],
  [5, ['cancel','CancelPage']],
  ['default', ['other','Index']]
])
/**
 * 按鈕點擊事件
 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消
 */
const onButtonClick = (status)=>{
  let action = actions.get(status) || actions.get('default')
  sendLog(action[0])
  jumpTo(action[1])
}

這樣寫用到了es6里的Map對象,是不是更爽了?Map對象和Object對象有什么區別呢?

  1. 一個對象通常都有自己的原型,所以一個對象總有一個"prototype"鍵。

  2. 一個對象的鍵只能是字符串或者Symbols,但一個Map的鍵可以是任意值。

  3. 你可以通過size屬性很容易地得到一個Map的鍵值對個數,而對象的鍵值對個數只能手動確認。

代碼風格

常量大寫

//bad code
const DAYS_IN_WEEK = 7;
const daysInMonth = 30;
const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const Artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];
function eraseDatabase() {}
function restore_database() {}
class animal {}
class Alpaca {}
//better code
const DAYS_IN_WEEK = 7;
const DAYS_IN_MONTH = 30;
const SONGS = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];
const ARTISTS = ['ACDC', 'Led Zeppelin', 'The Beatles'];
function eraseDatabase() {}
function restoreDatabase() {}
class Animal {}
class Alpaca {}

先聲明后調用

//bad code
class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }
  lookupPeers() {
    return db.lookup(this.employee, 'peers');
  }
  lookupManager() {
    return db.lookup(this.employee, 'manager');
  }
  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }
  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }
  getManagerReview() {
    const manager = this.lookupManager();
  }
  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

//better code
class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }
  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }
  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }
  lookupPeers() {
    return db.lookup(this.employee, 'peers');
  }
  getManagerReview() {
    const manager = this.lookupManager();
  }
  lookupManager() {
    return db.lookup(this.employee, 'manager');
  }
  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

以上就是淺談寫出優雅耐看 JS代碼 的方法的詳細內容,更多請關注億速云其它相關文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

云南省| 静海县| 富源县| 广南县| 常州市| 乳源| 雷波县| 子长县| 类乌齐县| 法库县| 胶州市| 砀山县| 高雄市| 德江县| 洪湖市| 孟津县| 无为县| 甘肃省| 巫溪县| 汽车| 西充县| 黄石市| 渭源县| 南投县| 吉安市| 建湖县| 辉县市| 尉犁县| 光山县| 新田县| 白河县| 杭锦后旗| 河东区| 从化市| 芷江| 林西县| 团风县| 兴仁县| 志丹县| 宁武县| 安图县|