1. ES6的解構
ES6中引入了解構賦值的操作,其作用是:將值從數組Array或屬性從對象Object提取到不同的變量中
即分為兩種情況:從數組Array中解構,以及從對象Object中解構
①.從數組中解構
const [a, b] = [1, 2]
//a = 1, b = 2
當然這些是基本的數組解構賦值,你還可以用逗號,進行跨值解構,用擴展運算符...進行多余項的解構等等
②.從對象中結構
const {a, b} = {a: 1, a: 2}
//a = 1, b = 2
這也是基本的對象結構賦值,不過在這里提一下,你仍然可以用擴展運算符...進行多余項的解構:
const {a, ...b} = {a: 1, b: 2, c: 3, d: 4}
//a = 1
//b = {b: 2, c: 3, d: 4}
③. 其他類型
當解構其他類型時,也是先將其他類型值轉換為Array或者Object
const [a, b, c] = 'hello'
// a = 'h', b = 'e', c = 'l'
const {toString: a} = true
toString === Boolean.prototype.toString // true
2. ES6的函數默認參數
① 定義
函數默認參數允許在沒有值或undefined被傳入時使用默認形參。
栗子:
function foo (a = 1, b = 2) {
console.log(a, b)
}
foo ()// 1 2
Note: 形參默認是undefiend, 也就是說,在沒有默認值時,a = undefiend, b = undefined;不過上面這個例子是沒有值被傳入的情況
undefiend被傳入的情況如下:
function foo (a = 1, b = 2) {
console.log(a, b)
}
foo (undefined, window.valueIsNotDefined)// 1 2
② 默認值不是只有函數參數才能用
還是直接舉個例子:
var {a = 1, b = 2} = {}
// a = 1, b = 2
var {a = 1, b = 2} = {a: 'hello'}
// a = 'hello', b = 2
其實解構賦值也是可以賦值默認值的;由此可見:
函數參數默認值的本質,還是解構賦值
3. 一個有趣的小栗子
說了那么多廢話,終於要說到這個小栗子了。
Step 1
這是一種超常見的情況,有的時候,當我們定義函數參數的時候,可以去解構當前的參數
比如:
function foo ({ a, b }) {
console.log(a, b)
}
foo({ a: 1, b: 2 })// 1 2
Note: 可以看成做了以下操作:
const { a, b } = { a: 1, b: 2 };
console.log(a, b)
Step 2
更多的時候,我們不會滿足於此,我們想要一個默認值
function foo ({a = 1, b = 2}) {
console.log(a, b)
}
foo({})// 1 2
Note: 可以看成做了以下操作:
const { a = 1, b = 2 } = {};
console.log(a, b)
問題 1
然而,我們實際使用時,不會用foo({})這種寫法來表示參數缺省,我們大多數人采用foo()這種顯而易見的寫法,由此問題來了
function foo ({a = 1, b = 2}) {
console.log(a, b)
}
foo()
Uncaught TypeError: Cannot destructure property `a` of 'undefined' or 'null'.
at foo (<anonymous>:1:14)
at <anonymous>:4:1
通過換一種寫法,不難發現錯誤原因:
const {a = 1, b = 2} = undefined // Error
解決方法:
其實,function foo ({a = 1, b = 2}) {}是對第一個參數的解構,那我們完全按照文章前面函數默認參數定義的那樣,在參數為undefined或沒有傳入的時候,預先定義:
function foo ({a, b} = {a: 1, b: 2}) {
console.log(a, b)
}
foo()// 1 2
分析:可以看做以下寫法
function foo (temp = {a: 1, b: 2}) {
var {a, b} = temp
console.log(a, b)
}
foo()// 1 2
問題 2
上面這種方法看似解決了問題,但當我們回過頭來,重新運行foo({}),卻出現了錯誤:
function foo ({a, b} = {a: 1, b: 2}) {
console.log(a, b)
}
foo({}) // undefined undefined
經歷了前面情景的分析后,不難發現:此時的函數參數傳入了一個有效值,所以temp不會去采納默認值,而是去采納有效的傳入值{}; 而var { a, b } = {}的解構,自然而然會讓a和b變為undefined
解決方法:
var { a = 1, b = 2 } = {}的形式,可以解決這種情況,原函數寫作:
function foo ({ a = 1, b = 2 } = {}) {
console.log(a, b)
}
foo()// 1 2
foo({})//1 2