日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前段時間有一個叫做“人類高質量男性”的視頻火了,相信很多同學都刷到過。所以今天給大家分享下,什么叫做“人類高質量代碼”,哈哈,開個玩笑。

其實分享的都是一些自己平時總結的小技巧,算是拋磚引玉吧,希望能給大家帶來一些啟發和幫助。

如何編寫出高質量的 JAVAScript 代碼?我個人認為,如果要編寫出高質量的 JavaScript 代碼,可以從以下三個方面去考慮。

分別是:易閱讀的代碼、高性能的代碼、健壯性的代碼。下面我將分別對這三個方面進行闡述。

易閱讀的代碼

首先說一下,代碼是寫給自己或團隊成員看的,良好的閱讀方式是編寫高質量代碼的前提條件。這里總結了四點具體操作方式分享給大家。

第一點:統一代碼格式

不要一會這樣寫,一會那樣寫,盡量統一寫法,下面舉例。

// bad
function foo(x,y) {
  return {
    sum : x + y
  };
}
function bar(m, n){
  let ret = m*n
  return ret;
}
// good
function foo(x, y) {    //  適當的空格隔開,一般符號前不添加空格,符號后添加空格
  return {
    sum: x + y,         //  拖尾逗號是合法的,簡化了對象和數組添加或刪除元素
  }                     //  省略結束分號,當然需要知道如何規避風險
}
function bar(m, n) {
  let ret = m * n
  return ret
}

人為去約定代碼格式,是很不方便的,所以可以借助一些工具進行自動格式轉換。

第二點:去除魔術數字

魔術數字(magic number)是程式設計中所謂的直接寫在程式碼里的具體數值(如“10”“123”等以數字直接寫出的值)。雖然程式作者寫的時候自己能了解數值的意義,但對其他程式員而言,甚至作者本人經過一段時間后,都會很難理解這個數值的用途。

// bad
setTimeout(blastOff, 86400000)
document.onkeydown = function (ev) {
  if (ev.keyCode === 13) {
    // todos
  }
}
// good
const MILLISECONDS_IN_A_DAY = 86400000
const ENTER_KEY = 13
setTimeout(blastOff, MILLISECONDS_IN_A_DAY)
document.onkeydown = function (ev) {
  if (ev.keyCode === ENTER_KEY) {
    // todos
  }
}

當然還有魔術字符串也是像上面一樣去處理,上面代碼中的常量命名推薦采用下劃線命名的方式,其他如變量、函數等推薦用駝峰進行命名。

其實減少this的使用頻率也是一樣的道理,當代碼中充斥著大量this的時候,我們往往很難知道它是誰,需要花費很多時間進行閱讀。

// bad
class Foo {
    foo() {
        this.number = 100
        this.el.onclick = function () {
            this.className = "active"
        }
    }
}
// good
class Foo {
    foo() {
        let context = this
        context.number = 100
        context.el.onclick = function () {
            let el = this
            el.className = "active"
        }
    }
}

第三點:單一功能原則

無論是編寫模塊、類、還是函數都應該讓他們各自都只有單一的功能,不要讓他們做過多的事情,這樣閱讀起來會非常簡單,擴展起來也會非常靈活。

// bad
function copy(obj, deep) {
  if (deep) {
    // 深拷貝
  } else {
    // 淺拷貝
  }
}
// good
function copy(obj) {
  // 淺拷貝
}
function deepCopy(obj) {
  // 深拷貝
}

第四點:減少嵌套層級

多層級的嵌套,如:條件嵌套、循環嵌套、回調嵌套等,對于代碼閱讀是非常不利的,所以應盡量減少嵌套的層級。

像解決條件嵌套的問題,一般可采用衛語句(guard clause)的方式提前返回,從而減少嵌套。

// bad
function foo() {
  let result
  if (isDead) {
    result = deadAmount()
  } else {
    if (isRet) {
      result = retAmount()
    } else {
      result = normalAmount()
    }
  }
  return result
}
// good
function foo() {
  if (isDead) {
    return deadAmount()
  }
  if (isRet) {
    return retAmount()
  }
  return normalAmount()
}

除了衛語句外,通過還可以采用短路運算、條件運算符等進行條件語句的改寫。

// bad
function foo() {
    if (isOk) {
        todo()
    }
    let grade
    if (isAdmin) {
        grade = 1
    } else {
        grade = 0
    }
}
// good
function foo() {
    isOk && todo()                   // 短路運算
    let grade = isAdmin ? 1 : 0      // 條件運算符
}

像解決回調嵌套的問題,一般可采用“async/await”方式進行改寫。

// bad
let fs = require("fs")
function init() {
  fs.mkdir(root, (err) => {
    fs.mkdir(path.join(root, "public", "stylesheets"), (err) => {
      fs.writeFile(
        path.join(root, "public", "stylesheets", "style.css"),
        "",
        function (err) {}
      )
    })
  })
}
init()
// good
let fs = require("fs").promises
async function init() {
  await fs.mkdir(root)
  await fs.mkdir(path.join(root, "public", "stylesheets"))
  await fs.writeFile(path.join(root, "public", "stylesheets", "style.css"), "")
}
init()

除了以上介紹的四點建議外,還有很多可以改善閱讀體驗的點,如:有效的注釋、避免不同類型的比較、避免生澀的語法等等。

高性能的代碼

在軟件開發中,代碼的性能高低會直接影響到產品的用戶體驗,所以高質量的代碼必然是高性能的。這里總結了四點具體操作方式分享給大家。

提示:測試JavaScript平均耗時,可使用console.time()方法、JSBench.Me工具、performance工具等。

第一點:優化算法

遞歸是一種常見的算法,下面是用遞歸實現的“求階乘”的操作。

// bad
function foo(n) {
  if (n === 1) {
    return 1
  }
  return n * foo(n - 1)
}
foo(100)   // 平均耗時:0.47ms
// good
function foo(n, result = 1) {
  if (n === 1) {
    return result
  }
  return foo(n - 1, n * result)    // 這里尾調用優化
}
foo(100)   // 平均耗時:0.09ms

“尾調用”是一種可以重用棧幀的內存管理優化機制,即外部函數的返回值是一個內部函數的返回值。

第二點:使用內置方法

很多功能都可以采用JavaScript內置方法來解決,往往內置方法的底層實現是最優的,并且內置方法可在解釋器中提前執行,所以執行效率非常高。

下面舉例為:獲取對象屬性和值的復合數組形式。

// bad
let data = {
  username: "leo",
  age: 20,
  gender: "male",
}
let result = []
for (let attr in data) {
  result.push([attr, data[attr]])
}
console.log(result)
// good
let data = {
  username: "leo",
  age: 20,
  gender: "male",
}
let result = Object.entries(data)
console.log(result)

第三點:減少作用域鏈查找

作用域鏈是作用域規則的實現,通過作用域鏈的實現,變量在它的作用域內可被訪問,函數在它的作用域內可被調用。作用域鏈是一個只能單向訪問的鏈表,這個鏈表上的每個節點就是執行上下文的變量對象(代碼執行時就是活動對象),單向鏈表的頭部(可被第一個訪問的節點)始終都是當前正在被調用執行的函數的變量對象(活動對象),尾部始終是全局活動對象。

概念太復雜的話, 看下面這樣一張圖。

 

作用域鏈這個鏈表就是 3(頭部:bar) -> 2(foo) -> 1(尾部:全局),所以查找變量的時候,應盡量在頭部完成獲取,這樣就可以節省性能,具體對比如下。

// bad
function foo() {
  $("li").click(function () {     // 全局查找一次
    $("li").hide()                // 再次全局查找一次
    $(this).show()
  })
}
// good
function foo() {
  let $li = $("li")               // 減少下面$li的作用域查找層級      
  $li.click(function () {      
    $li.hide()               
    $(this).show()
  })
}

除了減少作用域鏈查找外,減少對象屬性的查找也是一樣的道理。

// bad
function isNull(arg) {
  return Object.prototype.toString.call(arg) === "[object Null]"
}
function isFunction(arg) {
  return Object.prototype.toString.call(arg) === "[object Function]"
}
// good
let toString = Object.prototype.toString
function isNull(arg) {
  return toString.call(arg) === "[object Null]"
}
function isFunction(arg) {
  return toString.call(arg) === "[object Function]"
}

第四點:避免做重復的代碼

有時候編寫程序時,會出現很多重復執行的代碼,最好要避免做重復操作。先舉一個簡單的例子,通過循環找到第一個滿足條件元素的索引位置。

// bad
let index = 0
for (let i = 0, len = li.length; i < len; i++) {
    if (li[i].dataset.switch === "on") {
        index = i
    }
}
// good
let index = 0
for (let i = 0, len = li.length; i < len; i++) {
    if (li[i].dataset.switch === "on") {
        index = i
        break        // 后面的循環沒有意義,屬于執行不必要的代碼
    }
}

再來看一個計算“斐波那契數列”的案例。

// bad
function foo(n) {
  if (n < 3) {
    return 1
  }
  return foo(n - 1) + foo(n - 2)
}
foo(40)     // 平均耗時:1043ms
// good
let cache = {}
function foo(n) {
  if (n < 3) {
    return 1
  }
  if (!cache[n]) {
    cache[n] = foo(n - 1) + foo(n - 2)
  }
  return cache[n]
}
foo(40)    // 平均耗時:0.16ms

這里把遞歸執行過的結果緩存到數組中,這樣接下來重復的代碼就可以直接讀取緩存中的數據了,從而大幅度提升性能。

 

畫叉號的部分就會走緩存,而不會重復執行計算。

除了以上介紹的四點建議外,還有很多可以改善代碼性能的點,如:減少DOM操作、節流處理、事件委托等等。

健壯性的代碼

所謂健壯性的代碼,就是編寫出來的代碼,是可擴展、可維護、可測試的代碼。這里總結了四點具體操作方式分享給大家。

第一點:使用新語法

很多新語法可彌補之前語法的BUG,讓代碼更加健壯,應對未來。

// bad
var a = 1
isNaN(NaN)              // true
isNaN(undefined)        // true
// good
let a = 1
Number.isNaN(NaN)       // true
Number.isNaN(undefined) // false
新語法還可以簡化之前的操作,讓代碼結構更加清晰。
// bad
let user = { name: "james", age: 36 }
function foo() {
  let arg = arguments
  let name = user.name
  let age = user.age
}
// good
let user = { name: "james", age: 36 }
function foo(...arg) {          // 剩余參數
  let { name, age } = user      // 解構賦值
}

第二點:隨時可擴展

由于產品需求總是會有新的變更,對軟件的可擴展能力提出了很高要求,所以健壯的代碼都是可以隨時做出調整的代碼。

// bad
function foo(animal) {
  if (animal === "dog" || animal === "cat") {
    // todos
  }
}
function bar(name, age) {}
bar("james", 36)
// good
function foo(animal) {
  const animals = ["dog", "cat", "hamster", "turtle"]   // 可擴展匹配值
  if (animals.includes(animal)) {
    // todos
  }
}
function bar(options) {}    // 可擴展任意參數
bar({
  gender: "male",
  name: "james",
  age: 36,
})

第三點:避免副作用

當函數產生了除了“接收一個值并返回一個結果”之外的行為時,就產生了副作用。副作用不是說一定是有害的,但是如果在項目中沒有節制的引起副作用,代碼出錯的可能性會非常大。

建議盡量不要去修改全局變量或可變對象,通過參數和return完成需求。讓函數成為一種純函數,這樣也可使代碼更容易被測試。

// bad
let fruits = "Apple Banana"
function splitFruits() {
  fruits = fruits.split(" ")
}
function addItemToCart(cart, item) {
  cart.push({ item, data: Date.now() })
}
// good
let fruits = "Apple Banana"
function splitFruits(fruits) {    
  return fruits.split(" ")
}
function addItemToCart(cart, item) {
  return [...cart, { item, data: Date.now() }]
}

第四點:整合邏輯關注點

當項目過于復雜的時候,經常會把各種邏輯混在一起,對后續擴展非常不利,而且還影響對代碼的理解。所以盡量把相關的邏輯抽離到一起,進行集中式的管理。像React中的hooks,Vue3中的Composition API都是采用這樣的思想。

// bad
export default {
  name: 'App',
  data(){
    return {
      searchHot: [],
      searchSuggest: [],
      searchHistory: [],
    },
    mounted() {
      // todo hot
      
      // todo history
    },
    methods: {
      handleSearchSuggest(){
        // todo suggest
      },
      handleSearchHistory(){
        // todo history
      }
    }
  }
}
// good
export default {
  name: "App",
  setup() {
    let { searchHot } = useSearchHot()
    let { searchSuggest, handleSearchSuggest } = useSearchSuggest()
    let { searchHistory, handleSearchHistory } = useSearchHistory()
    return {
      searchHot,
      searchSuggest,
      searchHistory,
      handleSearchSuggest,
      handleSearchHistory,
    }
  }
}
function useSearchHot() {
  // todo hot
}
function useSearchSuggest() {
  // todo suggest
}
function useSearchHistory() {
  // todo history
}

除了以上介紹的四點建議外,還有很多可以改善代碼健壯性的點,如:異常處理、單元測試、使用TS替換JS等等。

最后總結一下,如何編寫高質量JavaScript代碼:

 

歡迎關注「慕課網」,發現更多IT圈優質內容,分享干貨知識,幫助你成為更好的程序員!

分享到:
標簽:JavaScript
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定