javascript 解构深层属性

w6lpcovy  于 2022-12-25  发布在  Java
关注(0)|答案(4)|浏览(149)

我最近开始使用ES6的destructuring赋值语法,并开始熟悉这个概念,我想知道是否可以使用相同的语法提取嵌套属性。
例如,假设我有以下代码:

let cagingIt = {
  foo: {
    bar: 'Nick Cage'
  }
};

我知道我可以通过执行以下操作将foo提取到变量中:

// where foo = { bar: "Nick Cage" }
let { foo } = cagingIt;

但是,是否可以提取一个嵌套很深的属性,比如bar

// where bar = "Nick Cage"
let { foo[bar] } = cagingIt;

我试着寻找关于此事的文件,但没有用。任何帮助将不胜感激。谢谢!

vdgimpew

vdgimpew1#

有一种方法可以使用这种语法来处理嵌套对象和数组。考虑到上面描述的问题,解决方案如下:

let cagingIt = {
      foo: {
        bar: 'Nick Cage'
      }
    };
let { foo: {bar: name} } = cagingIt;

console.log(name); // "Nick Cage"

在这个例子中,foo引用属性名“foo”。在冒号之后,我们使用bar引用属性“bar”。最后,name作为存储值的变量。
对于数组反结构化,您可以这样处理它:

let cagingIt = {
      foo: {
        bar: 'Nick Cage',
        counts: [1, 2, 3]
      }
    };

let { foo: {counts: [ ct1, ct2, ct3 ]} } = cagingIt;
console.log(ct2); // prints 2

它遵循与对象相同的概念,只是您可以使用数组解构并存储这些值。

lyr7nygr

lyr7nygr2#

如果您安装了lodash,则可以使用以下方法之一:

_.获取

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3

或者如果您需要多个密钥。

_.时间:

var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

_.at(object, ['a[0].b.c', 'a[1]']);
// => [3, 4]

您也可以安全地将_.at()与Array destructures.Handy配对,以便进行json响应。

[title, artist, release, artwork] = _.at(object, [
  'items[0].recording.title',
  'items[0].recording.artists[0].name',
  'items[0].recording.releases[0].title',
  'items[0].recording.releases[0].artwork[0].url'
]);
ilmyapht

ilmyapht3#

您可以将属性“as”解构为其他属性:

const { foo: myFoo } = { foo: 'bar' }  // myFoo == 'bar'

这里foo被反结构化为myFoo。您也可以将对象“as”反结构化为反结构化对象

const { foo: { bar } } = { foo: { bar: 'baz' } } // bar == 'baz'

在每种情况下只定义了一个变量,myFoobar,您可以看到它们也位于相似的位置,只是bar周围有{ }
您可以根据自己的喜好对任意多的嵌套层执行此操作,但是如果您不小心深入到太多的层次,您将得到旧的"Cannot read properties of undefined(reading 'foo')"

// Here's an example that doesn't work:
const foo = { bar: { notBaz: 1 } };
const { 
    bar: { 
        baz: { // baz is undefined in foo, so by trying to destructure it we're trying to access a property of 'undefined'
            qux
        }
    }
} = foo;
// throws Uncaught TypeError: Cannot read properties of undefined (reading 'baz')
// because baz is 'undefined'

// Won't run due to error above
console.log(qux);

在这种情况下,很明显我们不应该尝试去解构它,因为我们可以看到上一行中foo的定义没有定义属性baz。你不能总是保证你的 expected 结果的每个嵌套属性都是非null或非undefined的,你也不能事先知道。
可以通过添加= {}为结构破坏的对象设置默认值:

const { foo: myFoo = 'bar' } = { baz: 'qux' };  // myFoo == 'bar'
const { bar: { baz } = {} } = { qux: 'quuz' }   // baz == undefined 
// baz is destructured from the object that was set as the default for foo, which is undefined
// this would throw without the default object, as were trying to destructure from 'undefined'

您可以对深度嵌套的析构执行此操作:

// Here's an example that works:
const foo = { bar: { notBaz: 1 } };
const { 
    bar: { 
        baz: {
            qux    // you can default the final item to anything you like as well including null or undefined, but it will be undefined in this case
        } = {}     // if 'baz' undefined, return {}
    } = {}         // if 'bar' undefined, return {}
} = foo;

console.log(qux); // logs 'undefined'

如果任何一个属性是nullundefined,它将导致一个级联的返回空对象,其属性将在下一级被反结构化,将只是undefined .这是失控真的很快,虽然更深的对象,这可能是许多行代码与此格式.这里有另一个选项,做同样的事情.

const foo = { bar: { notBaz: 1 } };
const {qux} = foo?.bar?.baz ?? {}; // optional chaining and nullish coalescing

如果在foobarbaz过程沿着的任何一点为null或undefinednull,它将返回一个空对象,您可以对其进行反结构(??之后的空对象)。
如果你只需要提取一个属性,那么在{ qux }上使用反结构化就没有多大意义了,因为这也需要我们添加一个合并后的空值?? {}

const foo = { bar: { notBaz: 1 } };
const { qux, quux, quuz } = foo?.bar?.baz ?? {}; // this method is better for multiple properties
const quxFromBaz = foo?.bar?.baz?.qux;          // this method is better for single properties

就我个人而言,我认为包含所有可选的链接问号看起来有点混乱,但这比在每一层都使用嵌套的反结构化和默认值要好。
它可以处理数组

const foo = { 
    bar: [
        { a: 1 }, 
        { b: 2 }
    ] 
}
const c = foo?.bar?.[2]?.c   // c == undefined
// bar[2] will be undefined, so trying to access property 'c' would normally throw an error
slhcrj9b

slhcrj9b4#

三级深

为了帮助大家,这里有一段代码展示了如何解构三个层次的结构,在这个例子中,我对一个数组使用find()方法。

const id = someId
array.find(({ data: { document: { docId }, }, }) => docId == id)

上面的数组数据结构如下(数组中的每个obj都是相同的形状):

[{ 
   isSuccess: true, 
   isLoading: false,
   data: {
      foo: bar,
      ...,
      document: {
         docId: '123',
         ...
      },
}}]

相关问题