简体   繁体   English

JS/ES6:未定义的解构

[英]JS/ES6: Destructuring of undefined

I'm using some destructuring like this:我正在使用这样的解构:

const { item } = content
console.log(item)

But how should I handle content === undefined - which will throw an error?但是我应该如何处理content === undefined - 这会引发错误?

The 'old' way would look like this: “旧”方式如下所示:

const item = content && content.item

So, if content is undefined -> item will also be undefined.因此,如果content未定义 -> item也将是未定义的。

Can I do something similar using destructuring?我可以使用解构做类似的事情吗?

You can use short circuit evaluation to supply a default if content is a falsy value, usually undefined or null in this case.如果content为假值,您可以使用短路评估来提供默认值,在这种情况下通常为undefinednull

 const content = undefined const { item } = content || {} console.log(item) // undefined

A less idiomatic ( see this comment ) way is to spread the content into an object before destructuring it, because null and undefineds values are ignored .一种不太惯用的方法( 请参阅此评论)是在解构之前将内容传播到对象中,因为nullundefineds值被忽略

 const content = undefined const { item } = { ...content } console.log(item) // undefined

If you are destructuring function params you can supply a default ( = {} in the example).如果您正在解构函数参数,您可以提供一个默认值(示例中的= {} )。

Note: The default value would only be applied if the destructured param is undefined , which means that destructuring null values will throw an error.注意:只有在解构参数为undefined才会应用默认值,这意味着解构null值将引发错误。

 const getItem = ({ item } = {}) => item console.log(getItem({ item: "thing" })) // "thing" console.log(getItem()) // undefined try { getItem(null) } catch(e) { console.log(e.message) // Error - Cannot destructure property `item` of 'undefined' or 'null'. }

Or even set a default value for the item property if the input object doesn't contain the property如果输入对象不包含该属性,甚至可以为item属性设置默认值

 const getItem = ({ item = "default" } = {}) => item console.log(getItem({ item: "thing" })) // "thing" console.log(getItem({ foo: "bar" })) // "default"

const { item } = Object(content)
const content = undefined
const { item } = content ?? {}
console.log(item)   // undefined           

There is recently added: Nullish coalescing operator (??) .最近添加了: Nullish coalescing operator (??)
Which basically returns right-side value, if the left-side value is null or undefined (our case with undefined instead of an object).如果左侧值为 null 或未定义(我们的案例使用未定义而不是对象),则基本上返回右侧值。

const { item } = undefined or null
// Uncaught TypeError: Cannot destructure property 'item' of 'null' as it is  null.

const { item } = content ?? {}
console.log(item)   // undefined

So consider using the operator.所以考虑使用运算符。 Also, as mentioned before in the answers, there is ||另外,正如之前在答案中提到的,有|| (or) operator. (或)运营商。 For us, there is no significant difference in this particular case.对我们来说,在这种特殊情况下没有显着差异。

That's just a matter of taste, in our team, we have an agreement: we use ??这只是一个品味问题,在我们的团队中,我们有一个协议:我们使用?? for defining default object if the target object is null or undefined, and in other cases we use ||如果目标 object 是 null 或未定义,则用于定义默认值 object,在其他情况下我们使用|| operator.操作员。

accepted answer does not work for truely undefined values which were not set by const content = undefined .接受的答案不适用于不是由const content = undefined设置的真正未定义的值。 in such cases this will work:在这种情况下,这将起作用:

const { item } = (typeof content !== 'undefined' && content) || {}
console.log(item)

I'll just add that for the OP's use case, it is also possible to use the Optional chaining operator :对于 OP 的用例,我将补充一点,也可以使用Optional 链接运算符

const item = content?.item
console.log(item)

If content is null or undefined , then content.item will not be accessed and item will be undefined .如果contentnullundefined ,则不会访问content.item并且item将是undefined

One can unpack undefined value, but can't unpack from undefined.可以解包 undefined 值,但不能从 undefined 解包。
Fixing it is as easy as setting the default params value.修复它就像设置默认参数值一样简单。

Example:示例:

(() => {
    // prepare payload
    const PAYLOAD = {
        holdingJustThis: 1
    };
    // lets unpack the payload and more
    const {
        holdingJustThis,
        itIsGoingToBeUndefined,
        itCouldThrowButWont: {
            deep
        } = {}                  // this will secure unpacking "deep"
    } = PAYLOAD;

    console.log({
        holdingJustThis
    });
    console.log({
        itIsGoingToBeUndefined  // logs {itIsGoingToBeUndefined:undefined}
    });
    console.log({
        deep                    // logs {deep:undefined}
    });
})()

Destructuring the nested object is clean and short but sucks when source property is null or undefined in right side object解构嵌套对象既干净又简短,但在右侧对象中的源属性为 null 或未定义时很糟糕

let say we have假设我们有

const {
    loading,
    data: { getPosts },
  } = useQuery(FETCH_POSTS_QUERY);

Solution 1 if we have data object but no getPosts then we can use:解决方案 1如果我们有数据对象但没有getPosts那么我们可以使用:
(Setting default at each level) (在每个级别设置默认值)

   const { loading, data: { getPosts = [] } = { getPosts: [] } } =
useQuery(FETCH_POSTS_QUERY);

Solution 2: if event data is undefined then:解决方案 2:如果未定义事件数据,则:

  const { loading, data: { getPosts } = { getPosts: [] } } =
    useQuery(FETCH_POSTS_QUERY);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM