为所有元素在数组内解构对象属性

IT技术 javascript destructuring
2021-03-04 06:59:59

在最基本的形式中,有一个对象数组:

let arr = [
  {val:"a"},
  {val:"b"}
];

如何使用解构,仅获取值['a', 'b']

获取第一个值很容易:

let [{val:res}] = arr; //res contains 'a'

可以使用 rest 运算符获取数组中的所有值:

let [...res] = arr; //res contains all objects

结合这些,我希望能够使用:

let [...{val:res}] = arr; //undefined, expected all 'val's (['a', 'b'])

以上返回未定义(在 FF 中测试)。一些进一步的测试似乎表明,在使用对象解构时添加 rest 运算符也不使用迭代,而是取回原始对象,例如let [...{length:res}] = arr; //res= 2. 其他一些试验,例如let [{val:...res}] = arr;let [{val}:...res] = arr;产生语法错误。

使用其他方法很容易,例如map在数组上使用,但大多数情况下,我在解构多个级别(具有包含数组的自己的属性的对象的数组)时偶然发现了这个问题。因此,我真的试图绕过如何仅通过解构来做到这一点。为方便起见:一个测试小提琴

编辑

如果我未能解释问题的目的,我深表歉意。我不是在寻找特定问题的解决方案,只是为了在解构时找到要使用的正确语法。

否则,第一个问题将是:在上面的示例中,为什么不let [...{val:res}] = arr;返回所有值 ( ['a', 'b'])。第二个问题是:在嵌套对象解构中使用 rest 运算符的正确语法是什么?(很确定我在这里混淆了一些定义)。似乎不支持后者,但我没有遇到任何(以及为什么)不支持的文档。

5个回答

为什么不let [...{val:res}] = arr;返回所有值 ( ['a', 'b'])?

您似乎将其余语法与数组推导式混淆了。

如果给 赋值[someElements, ...someExpression],则测试该值是否可迭代,然后将迭代器生成的每个元素分配给相应的someElements变量。如果在解构表达式中使用 rest 语法,则会创建一个数组,并且迭代器会一直运行到结束,同时使用生成的值填充数组。然后将该数组分配给someExpression.

所有这些赋值目标都可以是其他解构表达式(任意嵌套和递归计算),或者对变量或属性的引用。

因此,如果您这样做let [...{val:res}] = arr,它将创建一个数组并使用以下迭代器中的所有值填充该数组arr

let {val:res} = Array.from(arr[Symbol.iterator]())

您现在可以看到为什么会以 结束undefined,以及为什么使用类似的东西[...{length:res}]会产生结果。另一个例子:

let [{val:res1}, ...{length: res2}] = arr;
console.log(res1) // 'a'
console.log(res2) // 1 (length of `[{val: 'b'}]`)

如何使用解构来仅获取值['a', 'b']

一点也不。使用map方法。

@guest271314 为什么?如果您参考您的帖子,这与我的回答有什么关系?
2021-04-23 06:59:59
“可以使用解构来仅获取值['a', 'b']吗?” . 答案中的“完全不是”部分。可以通过为从 右侧的输入数组中检索到的每个预期值声明一个唯一变量=,然后将定义的变量推送到数组中。尝试使用spreadelement 在解构赋值中使用 扩展数组{[prop]: [...res]},但尚未找到在下一个赋值索引处扩展"a"to的方法res
2021-05-09 06:59:59
明白你的意思 ...
2021-05-13 06:59:59
没有考虑任意长度的数组,因为 OP 中的数组只包含四个元素。对于任意长度的数组,这里的第一印象是尝试将变量分配为对象的属性,而不是例如a不知道这是否可能。将尝试这种方法。在这里发表评论的原因是由于您的答案的“根本不是”部分。如果你对答案的那部分没意见,我也在这里。还评论了,因为您可能会注意到答案的该部分可能有所改进
2021-05-15 06:59:59
@guest271314 如果声明多个变量,则它不适用于任意长度的数组。如果您使用循环,则不再是解构。
2021-05-20 06:59:59

您可以像这样解构嵌套对象

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Nested_object_and_array_destructuring

let arr = [
  {val:"a"},
  {val:"b"}
];

const [{val: valueOfA}, {val: valueOfB}] = arr

console.log(
  valueOfA, valueOfB
)

一次每个元素确实是可能的,但是对于未知数量的条目,您将如何做同样的事情?(不算for..of
2021-04-21 06:59:59
其实我完全不正确。您可以解构嵌套对象
2021-04-30 06:59:59
感谢您的回答。我知道map可以使用,我也可以for({val:v} of arr) console.log(v);用来组合解构和循环,甚至在 中使用解构map,但是如果可以在对象本身上使用 rest 运算符并且可以在嵌套属性上使用解构,那为什么不能使用 rest 运算符用于对象解构?我找不到有关其支持的文档,但也不支持它。
2021-05-07 06:59:59
@Me.Name "(不算..of )"为什么不能for..of用?什么是要求?
2021-05-15 06:59:59
for...of是一个迭代器循环,每次迭代都声明变量,与for...inorfor循环不同
2021-05-17 06:59:59

除了映射与值的回调

let arr = [{ val: "a" }, { val: "b" }];

console.log(arr.map(o => o.val));

您可以在参数列表中使用 deconstructiong 并仅使用要返回的值。

let arr = [{ val: "a" }, { val: "b" }];

console.log(arr.map(({val}) => val));

我的误解是结果,你想达到。我(非常)依赖示例,对我来说,不清楚您想要实现的目标。我看不到对象是源对象还是目标对象。如果包含源和目标,也许 itz 会更清楚。
2021-05-01 06:59:59
目标是找出如何(以及是否)可以使用解构来获取诸如此类的多个值。由于rest运算符存在(let [...res] = arr;有效)并且允许嵌套属性,为什么不let [...{val:res}] = arr;给出所有值。我假设这是我的某种疏忽,但我开始担心这是不可能的。不是具体的问题或者例子,所以我恐怕不能给出具体的来源和目标,只能举个例子。
2021-05-07 06:59:59
嗨尼娜。谢谢你回答我的帖子。我总是喜欢你的帖子和你提供的简洁答案:) 但是在这种情况下,这与特定场景无关,而是要找到通用的语法解决方案。我认为会有一种语法可以对未知数量的元素进行解构,因此可以在例如上使用相同的语法[{foo:1, arr:[ {val:"a"}, {val:"b"}]},{foo:2, arr:[ {val:"c"}, {val:"d"}]} ]
2021-05-11 06:59:59

此时,您可以将For of 循环ES6 Object destructuring 一起使用

let arr = [{val:"a"},{val:"b"}];
    
    
    for (const item in arr){
        const {val} = arr[item];
        console.log(val);
    }

您可以在解构赋值之前声明赋值目标;在解构目标处,通过解构源设置赋值目标索引的值

let arr1 = [{val: "a"}, {val: "b"}];

let arr2 = [{"foo":1,"arr":[{"val":"a"},{"val":"b"}]}
           , {"foo":2,"arr":[{"val":"c"},{"val":"d"}]}];

let [res1, res2] = [[], []];

[{val: res1[0]}, {val: res1[1]}] = arr1;

[{arr: [{val:res2[0]}, {val:res2[1]}]}
, {arr: [{val:res2[2]}, {val:res2[3]}]}] = arr2;

console.log(res1, res2);

您也可以使用rest elementat 目标来收集源中的值,方法是包含comma以下对象模式的运算符以返回从对象中提取的值

let arr = [{val: "a"}, {val: "b"}];

let [...res] = [({val} = arr[0], val), ({val} = arr[1], val)];

console.log(res)