本文列舉了一些日常會使用到的 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
,然後,同時使用 let
與 const
,任何動物年齡是會增長的,但是姓名不允許修改:
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
的值,賦值給一個名爲 name
的 const
變量。
看出問題來了吧? 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
這麼寫可能會提升閱讀難度,但是確實能節省代碼量,但是個人還是不太推薦在多人協作的項目裏面大量使用這樣的寫法。