如何培養良好的編程風格

前言: 雖然最近項目週期挺緊張的,晚上仍是儘可能擠出時間閱讀《編寫可維護的JavaScript》這本書籍。書籍總共分爲三部分(編程風格,編程實踐,自動化),本文是第一部分編程風格中我認爲比較精彩的片斷(檢測值 && 格式化),也應用在了當前的項目中,整理出來跟你們分享,但願對你們在重構優化代碼方面可以帶來必定的幫助。前端

情景引入

在JavaScript中,咱們經常會看到這種代碼:變量和null的比較(這種寫法頗有問題),用來判斷變量是否賦被賦予了一個合理的值。好比:正則表達式

var Controller = {
    process: function (items) {
        if (item !== null) { // 很差的寫法
            items.sort()
            items.forEach(item => {
                // 一些代碼
            })
        }
    }
}
複製代碼

在這段代碼中,process方法顯然是但願items是一個數組,由於咱們看到items擁有sort()和forEach().這段代碼的意圖很是明顯;若是參數items不是一個數組,則中止接下來的操做。咱們來分析一下,這種寫法的問題在於和null比較並不能真正避免錯誤的發生。items的值能夠是1,也能夠是字符串,甚至能夠是任意對象。這些值都和null不相等,進而會致使process()方法一旦執行到sort()時就會出錯。編程

僅僅和null比較並不能提供足夠的信息來判斷後續的代碼執行是否真的安全。好在JavaScript爲咱們提供了多種方法來檢測變量的真實值。數組

檢測值

1、檢測原始值

在JavaScript中有5種原始類型:字符串,數字,布爾值,undefined,null安全

對於字符串,數字,布爾值,undefined,最佳選擇是使用typeof運算符微信

示例代碼:函數

// 檢測字符串
if (typeof name === "string") {
  // 執行代碼
}

// 檢測數字
if (typeof count === "number") {
  // 一些代碼
}

// 檢測數字
if (typeof found === "boolean") {
  // 一些代碼
}

// 檢測undefined
if (typeof MyApp === "undefined") {
  // 一些代碼
}
複製代碼

對於null工具

null,通常不該用於檢測語句。正如上文情景引入中提到的,簡單地和null比較一般不會包含足夠的信息以判斷值的類型是否合法。但有一個例外,若是所指望的值真的是null,則能夠直接和null進行比較。 若是使用typeof運算符比較null,運行typeof null則返回'object',這是一種低效的判斷null的方法。 若是你須要驗證null,請直接使用恆等運算符(===)或非等運算符(!==) 示例代碼: 輸入框的值的判斷優化

if (this.skuName !== null) {
  // 輸入框有值才執行請求接口
  this.copySkuBlock()
} else {
  // 提示輸入框要輸入值
  this.$message({
    type: 'error',
    message: '請輸入商品規格'
  })
}
複製代碼

2、檢測引用值

在JavaScript鐘有4種引用類型:Object, Array, Date, 和Error。ui

示例代碼:

// 檢測日期
if (value instanceof Date) {
  // 一些代碼
}

// 檢測正則表達式
if (value instanceof RegExp) {
  // 一些代碼
}

// 檢測Error
if (value instanceof Error) {
  // 一些代碼
  throw value
}
複製代碼

3、檢測函數

從技術上講, JavaScript中的函數是引用類型,一樣存在Function構造函數。因爲instanceof運算符不能跨幀使用,typeof運算符則是檢測函數的最佳選擇

示例代碼:

function myFunc () {
// 很差的寫法 不能跨幀使用,由於每一個幀都有各自的Function構造函數
console.log(myFunc instanceof Function) // true
// 好的寫法 能跨幀使用, 但只能在IE9+使用
console.log(typeof myFunc === "function") // true
}
複製代碼

4、檢測數組

ES5將**Array.isArray()**的方法正式引入JavaScript,惟一的目的就是準確地檢測一個值是否爲數組,IE9+支持。

示例代碼:

function isArray () {
  if (typeof Array.isArray === "function") {
    return Array.isArray(value)
  } else {
    return Object.prototype.toString.call(value) === "[object Array]"
  }
}
複製代碼

5、檢測屬性

另一種用到null(以及undefined)的場景是當檢測一個屬性是否在對象中存在時。好比:

// 很差的寫法: 和null比較
if (object[propertyName] !== null) {
  // 一些代碼
}
複製代碼

判斷對象中的屬性是否存在最好的方法是使用in運算符。 in運算符僅僅會簡單地判斷屬性是否存在,而不會去讀屬性的值。

示例代碼:

A. 若是實例對象的屬性存在、或者繼承自對象的原型,in運算符都會返回true。好比:

if ("count" in object) {
  // 一些代碼
}
複製代碼

B. 若是你只想檢測實例對象的某個屬性是否存在,則使用hasOwnProperty()方法,僅支持IE9+

if (object.hasOwnproperty("count")) {
  // 一些代碼
}
複製代碼

所以,在判斷實例對象的屬性是否存在時,我更傾向於使用in運算符,只有在須要判斷實例屬性時纔會用到hasOwnproperty,這樣作能夠避免不少bug。

格式化

1、基本格式化

1.變量和函數, 都用小駝峯式命名,變量用名詞做前綴,函數用動詞做前綴。

2.禁止使用特殊值underfined,能夠有效地確保只在一種狀況下typeof纔會返回「underfined」

2、註釋

1.使用註釋的原則 當代碼不夠清晰時添加註釋,而當代碼很明瞭時不該當添加註釋當代碼不夠清晰時添加註釋,而當代碼很明瞭時不該當添加註釋

2.文檔註釋 開源項目中,強烈推薦用文檔生成工具來生成文檔註釋,好比YUIDoc或JSDoc Toolkit。 在Google內部的不少開源項目JSDoc Toolkit的應用很是普遍,這二者的區別在於,YUIDoc能夠同時支持文檔註釋中的HTML和Markdown格式,而JSDoc Toolkit 只支持HTML

三 語句和表達式

1.for循環

儘可能用條件語句代替for循環中的continue,更加容易理解且不容易出錯

示例代碼

// 很差的寫法
  var values = [0, 1, 2, 3, 4, 5, 6],
    i,len
  for (i = 0, len = values.length; i < len; i++) {
    if (i === 2 ) {
    // 跳過本次循環
    continue
    }
    console.log('第' + i + '次循環')
  }
  // 好的寫法
  var values = [0, 1, 2, 3, 4, 5, 6],
    i,len
  for (i = 0, len = values.length; i < len; i++) {
    if (i !== 2 ) {
    console.log('第' + i + '次循環')
    }
  }
複製代碼

2.for-in循環

for-in不只遍歷對象的實例屬性,一樣還會遍歷從原型繼承來的屬性。所以,當遍歷自定義對象的屬性時,for-in遍歷對象會遍歷從原型繼承來的屬性,建議使用hasOwnProperty()方法來爲for-in循環過濾出實例的屬性

示例代碼

// 好的寫法
var prop
for (prop in object) {
   if (object.hasOwnProperty(prop)) {
      console.log('Property name is' + prop)
      console.log('Property value is' + object[prop])
   }
}
複製代碼

我推薦老是在for-in循環中使用hasOwnProperty(), 除非你想查找原型鏈,這時應當補充註釋,好比:

// 好的寫法
var prop
for (prop in object) {  // 包含對原型鏈的遍歷
      console.log('Property name is' + prop)
      console.log('Property value is' + object[prop])
}
複製代碼

for-in循環是用來遍歷對象的,禁止用來遍歷數數組成員

示例代碼

// 很差的寫法
var values = [1, 2, 3],
    i
for (i in values) {
  console.log('Property name is' + i) // 0, 1, 2
  console.log('Property value is' + values[i]) // 1, 2, 3
}
複製代碼

4、變量、函數、運算符

1.變量聲明

將局部變量的定義做爲函數內第一條語句;全部的var語句合併爲一個語句,每一個變量的初始化獨佔一行。賦值運算符應當對齊。對於那些沒有初始值的變量來講,它們應當出如今var語句的尾部。

示例代碼

// 好的寫法
function doSomething () {
   // 局部遍歷的定義
   var value = 10,
       result = value + 10,
       i,
       len
   for (i = 0, len = items.length; i < len; i++) {
     doOtherSomething(items[i])
   }
}
複製代碼
  1. 嚴格模式

use strict 不只適用於全局,也適用於局部,可是最好不要在全局做用域中使用「use strict」模式

示例代碼

// 很差的寫法 全局的嚴格模式
'use strict'
function doSomething () {
  // 一些代碼
}
// 好的寫法
(function () {
 'use strict'
   function doSomething () {
      // 一些代碼
   }
   function doSomethingElse () {
     // 一些代碼
   }
})
複製代碼

3.運算符

因爲JavaScript具備強制類型轉換機制的緣故,咱們推薦不要使用==和!=,而是應當使用===和!==.

示例代碼

// 很差的寫法 字符串會被轉爲數字,而後再進行比較
console.log(5 == '5') // true
// 好的寫法
console.log(5 === '5') // false
複製代碼

4.函數

eval()

通用原則:嚴禁使用function,而且只在別無他法時使用eval()

總結

that's all, 以上就是我目前全部的對第一部分編程風格的理解以及應用。以爲對你開發有幫助的能夠點贊收藏一波,若是我哪裏寫錯了,但願能指點出來。若是你有更好的想法或者建議,能夠提出來在下方評論區與我交流。你們一塊兒進步,共同成長。感謝[鞠躬]。

一塊兒交流

我的的微信公衆號,付出的前端路,訂閱微信公衆號yhzg_gz(點擊複製,在微信中添加公衆號粘貼便可)

ps: 提升本身,常與異性交朋友

相關文章
相關標籤/搜索