成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何寫出優雅耐看的JavaScript代碼

開發 前端
在我們平時的工作開發中,大多數都是大人協同開發的公共項目;在我們平時開發中代碼codeing的時候我們考慮代碼的可讀性、復用性和擴展性。干凈的代碼,既在質量上較為可靠,也為后期維護、升級奠定了良好基礎。

前言

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

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

[[277405]]

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

變量

1、變量命名

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

 

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

2、可描述

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

 

  1. //bad code 
  2. const ADDRESS = 'One Infinite Loop, Cupertino 95014'
  3. const CITY_ZIP_CODE_REGEX = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; 
  4. saveCityZipCode(ADDRESS.match(CITY_ZIP_CODE_REGEX)[1], ADDRESS.match(CITY_ZIP_CODE_REGEX)[2]); 
  5.  
  6. //better code 
  7. const ADDRESS = 'One Infinite Loop, Cupertino 95014'
  8. const CITY_ZIP_CODE_REGEX = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; 
  9. const [, city, zipCode] = ADDRESS.match(CITY_ZIP_CODE_REGEX) || []; 
  10. saveCityZipCode(city, zipCode); 

3、形參命名

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

 

  1. //bad code 
  2. const locations = ['Austin''New York''San Francisco']; 
  3. locations.map((l) => { 
  4.   doStuff(); 
  5.   doSomeOtherStuff(); 
  6.   // ... 
  7.   // ... 
  8.   // ... 
  9.   // 需要看其他代碼才能確定 'l' 是干什么的。 
  10.   dispatch(l); 
  11. }); 
  12.  
  13. //better code 
  14. const locations = ['Austin''New York''San Francisco']; 
  15. locations.forEach((location) => { 
  16.   doStuff(); 
  17.   doSomeOtherStuff(); 
  18.   // ... 
  19.   // ... 
  20.   // ... 
  21.   dispatch(location); 
  22. }); 

4、避免無意義的前綴

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

 

  1. //bad code 
  2. const car = { 
  3.   carMake: 'Honda'
  4.   carModel: 'Accord'
  5.   carColor: 'Blue' 
  6. }; 
  7.  
  8. function paintCar(car) { 
  9.   car.carColor = 'Red'
  10.  
  11. //better code 
  12. const car = { 
  13.   make: 'Honda'
  14.   model: 'Accord'
  15.   color: 'Blue' 
  16. }; 
  17.  
  18. function paintCar(car) { 
  19.   car.color = 'Red'

5、默認值

 

  1. //bad code 
  2. function createMicrobrewery(name) { 
  3.   const breweryName = name || 'Hipster Brew Co.'
  4.   // ... 
  5.  
  6. //better code 
  7. function createMicrobrewery(name = 'Hipster Brew Co.') { 
  8.   // ... 

函數

1、參數

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

 

  1. //bad code 
  2. function createMenu(title, body, buttonText, cancellable) { 
  3.   // ... 
  4.  
  5. //better code 
  6. function createMenu({ title, body, buttonText, cancellable }) { 
  7.   // ... 
  8.  
  9. //better code 
  10. createMenu({ 
  11.   title: 'Foo'
  12.   body: 'Bar'
  13.   buttonText: 'Baz'
  14.   cancellable: true 
  15. }); 

2、單一化處理

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

 

  1. //bad code 
  2. function emailClients(clients) { 
  3.   clients.forEach((client) => { 
  4.     const clientRecord = database.lookup(client); 
  5.     if (clientRecord.isActive()) { 
  6.       email(client); 
  7.     } 
  8.   }); 
  9.  
  10. //better code 
  11. function emailActiveClients(clients) { 
  12.   clients 
  13.     .filter(isActiveClient) 
  14.     .forEach(email); 
  15. function isActiveClient(client) { 
  16.   const clientRecord = database.lookup(client);     
  17.   return clientRecord.isActive(); 

3、對象設置默認屬性

 

  1. //bad code 
  2. const menuConfig = { 
  3.   title: null
  4.   body: 'Bar'
  5.   buttonText: null
  6.   cancellable: true 
  7. }; 
  8. function createMenu(config) { 
  9.   config.title = config.title || 'Foo'
  10.   config.body = config.body || 'Bar'
  11.   config.buttonText = config.buttonText || 'Baz'
  12.   config.cancellable = config.cancellable !== undefined ? config.cancellable : true
  13. createMenu(menuConfig); 
  14.  
  15.  
  16. //better code 
  17. const menuConfig = { 
  18.   title: 'Order'
  19.   // 'body' key 缺失 
  20.   buttonText: 'Send'
  21.   cancellable: true 
  22. }; 

4、避免副作用

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

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

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

 

  1. //bad code 
  2. // 全局變量被一個函數引用 
  3. // 現在這個變量從字符串變成了數組,如果有其他的函數引用,會發生無法預見的錯誤。 
  4. var name = 'Ryan McDermott'
  5. function splitIntoFirstAndLastName() { 
  6.   name = name.split(' '); 
  7. splitIntoFirstAndLastName(); 
  8. console.log(name); // ['Ryan''McDermott']; 
  9.  
  10.  
  11. //better code 
  12. var name = 'Ryan McDermott'
  13. var newName = splitIntoFirstAndLastName(name
  14.  
  15. function splitIntoFirstAndLastName(name) { 
  16.   return name.split(' '); 
  17.  
  18. console.log(name); // 'Ryan McDermott'
  19. console.log(newName); // ['Ryan''McDermott']; 

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

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

看起來沒問題對不對?

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

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

 

  1. //bad code 
  2. const addItemToCart = (cart, item) => { 
  3.   cart.push({ item, dateDate.now() }); 
  4. }; 
  5.  
  6. //better code 
  7. const addItemToCart = (cart, item) => { 
  8.   return [...cart, {item, dateDate.now()}] 
  9. }; 

5、全局方法

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

 

  1. //bad code 
  2. Array.prototype.diff = function diff(comparisonArray) { 
  3.   const hash = new Set(comparisonArray); 
  4.   return this.filter(elem => !hash.has(elem)); 
  5. }; 
  6.  
  7. //better code 
  8. class SuperArray extends Array { 
  9.   diff(comparisonArray) { 
  10.     const hash = new Set(comparisonArray); 
  11.     return this.filter(elem => !hash.has(elem));         
  12.   } 

6、避免類型檢查

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

 

  1. //bad code 
  2. function travelToTexas(vehicle) { 
  3.   if (vehicle instanceof Bicycle) { 
  4.     vehicle.pedal(this.currentLocation, new Location('texas')); 
  5.   } else if (vehicle instanceof Car) { 
  6.     vehicle.drive(this.currentLocation, new Location('texas')); 
  7.   } 
  8.  
  9. //better code 
  10. function travelToTexas(vehicle) { 
  11.   vehicle.move(this.currentLocation, new Location('texas')); 

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

 

  1. //bad code 
  2. function combine(val1, val2) { 
  3.   if (typeof val1 === 'number' && typeof val2 === 'number' || 
  4.       typeof val1 === 'string' && typeof val2 === 'string') { 
  5.     return val1 + val2; 
  6.   } 
  7.  
  8.   throw new Error('Must be of type String or Number'); 
  9.  
  10. //better code 
  11. function combine(val1, val2) { 
  12.   return val1 + val2; 

復雜條件判斷

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

1、if/else

點擊列表按鈕事件

 

  1. /** 
  2.  * 按鈕點擊事件 
  3.  * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消 
  4.  */ 
  5. const onButtonClick = (status)=>{ 
  6.   if(status == 1){ 
  7.     sendLog('processing'
  8.     jumpTo('IndexPage'
  9.   }else if(status == 2){ 
  10.     sendLog('fail'
  11.     jumpTo('FailPage'
  12.   }else if(status == 3){ 
  13.     sendLog('fail'
  14.     jumpTo('FailPage'
  15.   }else if(status == 4){ 
  16.     sendLog('success'
  17.     jumpTo('SuccessPage'
  18.   }else if(status == 5){ 
  19.     sendLog('cancel'
  20.     jumpTo('CancelPage'
  21.   }else { 
  22.     sendLog('other'
  23.     jumpTo('Index'
  24.   } 

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

2、switch/case

 

  1. /** 
  2.  * 按鈕點擊事件 
  3.  * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消 
  4.  */ 
  5. const onButtonClick = (status)=>{ 
  6.   switch (status){ 
  7.     case 1: 
  8.       sendLog('processing'
  9.       jumpTo('IndexPage'
  10.       break 
  11.     case 2: 
  12.     case 3: 
  13.       sendLog('fail'
  14.       jumpTo('FailPage'
  15.       break   
  16.     case 4: 
  17.       sendLog('success'
  18.       jumpTo('SuccessPage'
  19.       break 
  20.     case 5: 
  21.       sendLog('cancel'
  22.       jumpTo('CancelPage'
  23.       break 
  24.     default
  25.       sendLog('other'
  26.       jumpTo('Index'
  27.       break 
  28.   } 

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

3、存放到Object

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

 

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

4、存放到Map

 

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

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

  • 一個對象通常都有自己的原型,所以一個對象總有一個"prototype"鍵。
  • 一個對象的鍵只能是字符串或者Symbols,但一個Map的鍵可以是任意值。

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

代碼風格

常量大寫

  1. //bad code 
  2. const DAYS_IN_WEEK = 7; 
  3. const daysInMonth = 30; 
  4.  
  5. const songs = ['Back In Black''Stairway to Heaven''Hey Jude']; 
  6. const Artists = ['ACDC''Led Zeppelin''The Beatles']; 
  7.  
  8. function eraseDatabase() {} 
  9. function restore_database() {} 
  10.  
  11. class animal {} 
  12. class Alpaca {} 
  13.  
  14. //better code 
  15. const DAYS_IN_WEEK = 7; 
  16. const DAYS_IN_MONTH = 30; 
  17.  
  18. const SONGS = ['Back In Black''Stairway to Heaven''Hey Jude']; 
  19. const ARTISTS = ['ACDC''Led Zeppelin''The Beatles']; 
  20.  
  21. function eraseDatabase() {} 
  22. function restoreDatabase() {} 
  23.  
  24. class Animal {} 
  25. class Alpaca {} 

先聲明后調用

 

  1. //bad code 
  2. class PerformanceReview { 
  3.   constructor(employee) { 
  4.     this.employee = employee; 
  5.   } 
  6.  
  7.   lookupPeers() { 
  8.     return db.lookup(this.employee, 'peers'); 
  9.   } 
  10.  
  11.   lookupManager() { 
  12.     return db.lookup(this.employee, 'manager'); 
  13.   } 
  14.  
  15.   getPeerReviews() { 
  16.     const peers = this.lookupPeers(); 
  17.     // ... 
  18.   } 
  19.  
  20.   perfReview() { 
  21.     this.getPeerReviews(); 
  22.     this.getManagerReview(); 
  23.     this.getSelfReview(); 
  24.   } 
  25.  
  26.   getManagerReview() { 
  27.     const manager = this.lookupManager(); 
  28.   } 
  29.  
  30.   getSelfReview() { 
  31.     // ... 
  32.   } 
  33.  
  34. const review = new PerformanceReview(employee); 
  35. review.perfReview(); 
  36.  
  37. //better code 
  38. class PerformanceReview { 
  39.   constructor(employee) { 
  40.     this.employee = employee; 
  41.   } 
  42.  
  43.   perfReview() { 
  44.     this.getPeerReviews(); 
  45.     this.getManagerReview(); 
  46.     this.getSelfReview(); 
  47.   } 
  48.  
  49.   getPeerReviews() { 
  50.     const peers = this.lookupPeers(); 
  51.     // ... 
  52.   } 
  53.  
  54.   lookupPeers() { 
  55.     return db.lookup(this.employee, 'peers'); 
  56.   } 
  57.  
  58.   getManagerReview() { 
  59.     const manager = this.lookupManager(); 
  60.   } 
  61.  
  62.   lookupManager() { 
  63.     return db.lookup(this.employee, 'manager'); 
  64.   } 
  65.  
  66.   getSelfReview() { 
  67.     // ... 
  68.   } 
  69.  
  70. const review = new PerformanceReview(employee); 
  71. review.perfReview(); 

 

責任編輯:未麗燕 來源: SegmentFault.com
相關推薦

2021-01-04 07:57:07

C++工具代碼

2022-03-11 12:14:43

CSS代碼前端

2021-11-30 10:20:24

JavaScript代碼前端

2021-09-01 08:55:20

JavaScript代碼開發

2020-05-14 09:15:52

設計模式SOLID 原則JS

2021-12-07 08:16:34

React 前端 組件

2020-07-15 08:17:16

代碼

2020-05-08 14:45:00

JS代碼變量

2020-05-11 15:23:58

CQRS代碼命令

2013-06-07 14:00:23

代碼維護

2022-02-08 19:33:13

技巧代碼格式

2022-02-17 10:05:21

CSS代碼前端

2020-12-19 10:45:08

Python代碼開發

2020-05-19 15:00:26

Bug代碼語言

2024-03-28 14:29:46

JavaScript編程

2024-12-04 15:10:21

2021-12-13 14:37:37

React組件前端

2015-09-28 10:49:59

代碼程序員

2019-06-24 10:26:15

代碼程序注釋

2022-10-24 08:10:21

SQL代碼業務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产伦精品一区二区三区四区视频 | 国产日产精品一区二区三区四区 | 国产成人福利在线观看 | 亚洲福利片 | 国产精品久久久久一区二区三区 | 日日夜夜视频 | 国产精品一区二区久久 | 久久天堂网 | 91精品国产综合久久香蕉922 | 国产一区不卡 | 久久精品网 | 日韩精品色网 | 欧美中文字幕一区二区三区 | 久久久久久91 | 美女操网站 | 一区二区三区视频在线免费观看 | 国内精品久久久久久 | 欧美又大粗又爽又黄大片视频 | 国产激情在线 | 久久国产精品久久久久久 | 国产精品久久久久久 | 精品国产乱码久久久久久1区2区 | 欧美成人精品欧美一级 | www.国产.com| 精品成人免费视频 | 国产成人精品一区二区三区四区 | 免费观看一级特黄欧美大片 | 久久精品国产99国产精品 | 亚洲精品99 | 99一级毛片 | 久久久蜜桃一区二区人 | 国产高清精品一区二区三区 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 中文字幕亚洲欧美日韩在线不卡 | 久久国产视频播放 | 国产精品99久久久久久宅男 | 性欧美xxxx| 国产日韩欧美一区二区 | 成人免费观看男女羞羞视频 | 色天天综合 | 久久草在线视频 |