面試題:一道關於解構賦值和引數預設值的程式設計題

山頭人漢波發表於2022-04-10

前端俱樂部QQ群中,有朋友發出這樣的題目,說最近面試中遇到了,如下所示

function fun( ? ) {
    return {a,b}
}
console.log(fun( )) // {a:1,b:2}
console.log(fun({a:3})) // {a:3,b:456}
console.log(fun({})) // {a:123,b:456}

問,fun 的引數應該填什麼?

提示:利用結構賦值和引數預設值

經過我一番測試,其結果如下所示:

function fun({ a = 123, b = 456 } = { a: 1, b: 2 }) {
  return { a, b }
}

解題思路

先看第一個執行: console.log(fun( )) // {a:1,b:2}

fun() 不傳引數,直接執行,結果 a 為 1,b 為 2。說明預設值為 a : 1,b : 2。

可以得出

function fun(a = 1, b = 2) {
  return { a, b }
}

再看第二個執行:console.log(fun({a:3})) // {a:3,b:456}

fun({a: 3}) ,引數傳入一個物件,物件中 a 為 3,其結果 a 為 3,b 為 456。說明其引數預設值為一個物件,物件中的值又有預設引數 a 與 b。

結合“執行 1”,如果不傳引數,預設用 a = 1, b = 2 的選項;如果傳入引數;則用物件中的預設引數。即

function fun({ a = XX, b = 456 } = { a: 1, b: 2 }) {
  return { a, b }
}

最後看第三個執行:console.log(fun({})) // {a:123,b:456}

很明顯,我們還不知道物件中的預設 a 代表什麼。第三個執行告訴我們它為 123

所以最後我們的答案是

function fun({ a = 123, b = 456 } = { a: 1, b: 2 }) {
  return { a, b }
}

難點

在做這道題的時候,我被賦值的 =: 迷惑了。這裡做筆記記錄

  • : 針對物件賦值
  • = 為預設值

如圖所示:

const obj = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
}
const { a, b } = obj // 解構賦值 a,b, a為1,b為2
const { a = 11, b = 21, e = 51 } = obj // 給解構賦值的 設定預設值,a為1,b為2,e為51,得預設值是當你物件中沒有值時,賦予該變數的預設值

= 賦予變數預設值

那麼 : 何處使用,當解構賦值中的值為一個物件的時,設定物件中的值就用

const obj = {
  a: {
    aa: 11,
    bb: 22,
  },
  b: 2,
  c: 3,
  d: 4,
}
const { a, b } = obj // a={aa: 11, bb: 22} b=2
const { a = { aa: 111, bb: 222 }, b = 22, e = { aa: 111, bb: 222 } } = obj
// a={aa: 11, bb: 22},b = 22, e={aa: 111, bb: 222}

這裡我們要注意:當解構的值在物件中,即使設定預設值,還是會以值為準;如果解構的值不在物件中,則會以預設值的形式出現在結果值中。

回頭看題

function fun( ? ) {
    return {a,b}
}
console.log(fun( )) // {a:1,b:2}
console.log(fun({a:3})) // {a:3,b:456}
console.log(fun({})) // {a:123,b:456}

為什麼 a = 123, b = 456 要用等於號=,而不是用冒號:呢,因為它原本是”鍵“,只能賦予預設值而不能將鍵重新命名

總結

解構賦值時,冒號: 是重新命名,等於號= 是賦值預設值

本文參與了 SegmentFault 思否徵文「如何“反殺”面試官?」,歡迎正在閱讀的你也加入。

相關文章