積極使用解構賦值以及箭頭函數提升 Javascript 表現力

本文列舉了一些日常會使用到的 Javascript技巧,可以明顯提升代碼的表現力。

解構賦值

首先,我們來看一下下面這段代碼:

const animal = {
  type: {
    mammal: {
      bear: {
        age: 12
      },
      deer: {
        age: 4
      }
    }
  }
}

console.log(animal.type.mammal.bear) // 輸出:{ age: 12 }
console.log(animal.type.mammal.deer) // 輸出:{ age: 4 }

對象解構賦值

其實我們可以利用解構賦值做得更好:

const animal = {
  type: {
    mammal: {
      bear: {
        age: 12
      },
      deer: {
        age: 4
      }
    }
  }
}

const { bear, deer } = animal.type.mammal
console.log(bear) // 輸出:{ age: 12 }
console.log(deer) // 輸出:{ age: 4 }

不管上面哪種實現方式,我們都使用的 const,這表示這些被定義的變量不允許再被賦值,我們推薦 在編寫 Javascript 代碼時,儘可能的使用 const,除非這個變量確實需要被多次賦值,比如,年齡是可以增長的:

const animal = {
  type: {
    mammal: {
      bear: {
        age: 12
      },
      deer: {
        age: 4
      }
    }
  }
}

const { age } = animal.type.mammal.bear

age += 1 // 這裏會報錯,因爲 age 是一個 const 變量

在這種情況下,我們可以將 const 改爲 let

const animal = {
  type: {
    mammal: {
      bear: {
        age: 12
      },
      deer: {
        age: 4
      }
    }
  }
}

let { age } = animal.type.mammal.bear

age += 1
console.log(age) // 輸出:13

接下來,我們給每一個 animal 增加一個姓名字段 name,然後,同時使用 letconst,任何動物年齡是會增長的,但是姓名不允許修改:

const animal = {
  type: {
    mammal: {
      bear: {
        name: 'Bug',
        age: 12
      },
      deer: {
        name: 'Debug',
        age: 4
      }
    }
  }
}

const { name } = animal.type.mammal.bear
let { age } = animal.type.mammal.bear

age += 1
console.log(age) // 輸出:13
console.log(name) // 輸出:Bug

數組解構賦值

我們現在有三隻動物,有一個數組保存了它們的名字:

const animalNames = ['Bug', 'Debug', 'Bugfix']
const [bug, debug, bugfix] = animalNames
console.log(debug) // 輸出:Debug

解構賦值時重命名

我們還有可能有這樣的需求,我想同時拿到上面示例中 animal 那個對象中,兩隻動物的姓名,這個時候我們可以完全按照對象的結構去解構它:

const animal = {
  type: {
    mammal: {
      bear: {
        name: 'Bug',
        age: 12
      },
      deer: {
        name: 'Debug',
        age: 4
      }
    }
  }
}

const { bear: { name }, deer: { name }} = animal.type.mammal

上面的意思是:從 animal.type.mammal 對象中,訪問 bear,並拿到它的 name 的值,並賦值給一個 const 變量,變量名爲 name,同時再從 deer 中拿到 name 的值,賦值給一個名爲 nameconst 變量。

看出問題來了吧? name 被聲明瞭兩次,這是不允許的,此時,我們可以在聲明時,爲兩個 name 指定不同的名稱:

const animal = {
  type: {
    mammal: {
      bear: {
        name: 'Bug',
        age: 12
      },
      deer: {
        name: 'Debug',
        age: 4
      }
    }
  }
}

const { bear: { name: bearName }, deer: { name: deerName }} = animal.type.mammal
console.log(bearName) // 輸出:Bug
console.log(deerName) // 輸出:Debug
數組的解構中同樣支持重命名。

箭頭函數

箭頭函數可以大大減少編碼工作量,但是它們並非普通函數的完全替代者,先來看看下面的代碼:

const animals = ['Bug', 'Debug', 'Bugfix']

animals.forEach(function (animal) {
  console.log(animal)
})

我們使用箭頭函數改寫上面的代碼:

const animals = ['Bug', 'Debug', 'Bugfix']

animals.forEach(animal => {
  console.log(animal)
})

這是一個簡單的示例,只是爲了證明箭頭函數能讓我們的代碼更清晰可讀,編碼量也能大大減少,有一個不成文的經驗是,一個項目的代碼量越少,維護的成本一般情況下,都會越低,那爲了證明箭頭函數確實有用,我們再來看一個更復雜點的例子:

function multiplyAndAdd(multiply) {
  const pow = multiply ** multiply
  return function (number) {
    return pow + number
  }
}

const result = multipleAndAdd(3)(5) // 等於:3 ** 3 + 5 = 27 + 5 = 32

console.log(result) // 輸出:32

用箭頭函數再來改寫一次:

const multiplyAndAdd = multiply => {
  const pow = multiply ** multiply
  return number => pow + number
}

如果熟練的話,我一般會這麼寫:

const multiplyAndAdd = multiply => number => multiply ** multiply + number

這裏面可以這麼閱讀:

  • 聲明一個 const 值:multiplyAndAdd,它的值爲 multiply => number => multiply ** multiply + number,這個都很好理解
  • 這個值是一個箭頭函數,該函數接受一個名爲 multiply 的參數,返回 number => multiply ** multiply + number
  • 它的返回值還是一個箭頭函數,這個箭頭函數接受一個 number 參數,返回 multiply ** multiply + number
這麼寫可能會提升閱讀難度,但是確實能節省代碼量,但是個人還是不太推薦在多人協作的項目裏面大量使用這樣的寫法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章