解構給預設值 解構賦值預設值誤區

2021-10-17 02:30:41 字數 1755 閱讀 3481

問題還原

這是最近 cr 的時候在業務**中發現了乙個問題,先來看一下問題**:

// data 為介面返回的資料

const , total = 0 } = data.result || {};

const list = bizobject.list || ;

// 其他邏輯,比如把 list 更新到 state 中,等等

a 介面正常的情況:data 中有 result 屬性,且 result 物件中 bizobject 返回了乙個數—— ✅

b 介面異常:data 物件中沒有 result 屬性 —— ✅

c 介面異常:data 中有 result 屬性,result 物件中也有 bizobject 屬性,但是,bizobject 屬性的值是 null,然後呢?

從上下文來看,這位同學應該是期望解構賦值按以下方式執行:

const result = data.result || {};

const bizobject = result.bizobject || {};

但是,c 情形拋異常了:

uncaught typeerror: cannot read property 'list' of null

也就是 bizobject 的值是 null 而不是期望的 {}。為什麼呢?

解構賦值中的預設值

a variable can be assigned a default, in the case that the value unpacked from the object/array is undefined.

陣列、物件解構賦值時,只有當屬性(陣列索引對應的值)值為 undefined 時,才會使用預設值。

問題**中,當 bizobject 為 null 時,解構出來的就是 null,讀取 null 的 list 屬性,不報錯才怪。

函式預設引數

再來看看函式的預設引數是不是同樣的邏輯:

function dosomething(options = )

dosomething(undefined); //

dosomething(null); // null

不傳引數(隱式的 undefined)或者顯示地傳遞 undefined,使用了預設引數,傳 null 的時候沒有使用預設值,和解構賦值的預設值同樣的邏輯。

其實把上面的函式轉成 es5,就能直觀地了解其邏輯:

function dosomething() = ;

// 轉換成 es5

var _ref = {},

_ref$a = _ref.a,

a = _ref$a === void 0 ? 1 : _ref$a;

寫在最後

之所以會有同學把解構賦值預設值等同於 const bizobject = result.bizobject || {},可能是對 es6 的一些細節了解得不夠透徹,可以多翻翻文件:

還有乙個可能,前端同學並沒有誤解解構賦值預設值的工作原理,只是介面不規範引發了異常。一般而言,介面約定好欄位、型別後,就應該始終按約定的型別返回資料,約定的是物件,那沒有資料的時候也應該返回乙個空物件,即使不返回這個字段,前端也已經判斷了,莫名其妙地返回乙個 null 算哪門子事?

介面寫得有問題,有的人溝通一下還是會調整,有的人就始終一副「**不羈」樣子,通了就行,才不管你什麼規範、約定……對於不講究的人,還是自己多寫兩行**判斷一下,說多了也是浪費,***。

很多事情都是 100% 的期望,然後妥協,接受乙個差不多的結果。(bgm 差不多先生 - mc hot dog)

函式引數的預設值與解構賦值的預設值

function foo 物件,沒有預設值,只有解構賦值引數的預設值 console.log x,y foo undefined 5 foo 1 5 foo 1 2 foo typeerror cannot read property x of undefined上面 只使用了物件的解構賦值預設值,...

解構給預設值 ES6系列(二)解構賦值

之前在我們開發的過程中,難免會碰到這樣的問題 後端傳給我們一串資料,然後我們需要對這個資料進行處理。如果是這樣的乙個資料 let obj 然後我們需要用變數去儲存這些資料,那麼我們可能會這麼操作 let username obj.username,userid obj.userid,professi...

解構給預設值 ES6系列之解構賦值

我們之前談過了es6在變數宣告這一塊的小改動,忘了的同學可以戳藍字複習 前端初學者,也能輕鬆掌握es6 今天我們來 乙個新問題 之前在我們開發的過程中,難免會碰到這樣的情況 後端傳給我們一串資料,然後我們需要對這個資料進行處理。如果是這樣的乙個資料 let obj 然後我們需要用變數去儲存這些資料,...