javascript 为什么对象合并属性而数组不合并值

6ie5vjzr  于 2022-12-10  发布在  Java
关注(0)|答案(2)|浏览(169)

有人能说出为什么对象合并值而数组不合并吗
请参见下面的代码块:

const a = {'a': 1, 'b': 2}
const b = {'b': 4, 'c': 3}
console.log({...a, ...b})

此输出

{ a: 1, b: 4, c: 3 }

但是当我使用下面的代码时:

const c = [1,2]
const d = [2,3]
console.log([...c, ...d])

此输出

[ 1, 2, 2, 3 ]
wdebmtf2

wdebmtf21#

为什么对象合并属性...
它不合并 properties,而是合并 objects。注意结果中b的值:它是4(来自b对象的值),而不是2(来自a对象)和4(来自b对象)的某个合并值。每个源对象的每个属性只是被复制到目标对象中(后面的对象覆盖前面对象的属性),属性本身并没有合并在一起。
但从根本上说,对象属性扩展和可迭代扩展只是完全不同的东西,具有不同的目的和不同的语义,因为对象和数组是不同的野兽(至少在概念上;数组实际上是JavaScript中的对象)。属性有 names,它是属性的内在部分。数组元素只有索引,并且在数组中移动值是正常的(移动到不同的索引)。spread的两种不同定义对于它们定义的数据类型都很有用。
如果你想把数组当作对象来处理,你可以这样做,因为数组在JavaScript中是对象。(尽管在这种情况下它没有什么用处。)下面是一个例子(我已经修改了c的元素值,这样就清楚了什么来自哪里):

const c = ["a", "b"];
const d = [2, 3];
console.log(Object.assign([], c, d));

在这种情况下,由于d同时具有索引01的值,因此c的元素都不在结果中。但是:

const c = ["a", "b", "c", "d", "e"];
const d = [2, 3];
console.log(Object.assign([], c, d));
4c8rllxm

4c8rllxm2#

简短回答

  • 使用分摊运算符时,常规对象为ASSIGNED
  • 使用spread运算符时,数组为CONCATENATED

我相信你困惑的根源是JavaScript中的每个数组都只是一个属于Array构造函数的对象。那么,为什么用spread操作符连接两个或更多数组的方式与连接对象的方式不同呢?

让我们分析一下对象的情况

const a = {'a': 1, 'b': 2};
const b = {'b': 4, 'c': 3};
console.log({...a, ...b}); // Output: { a: 1, b: 4, c: 3 }
console.log(Object.assign({}, a, b)); // Output: { a: 1, b: 4, c: 3 }
console.log({...b, ...a}); // Output: { a: 1, b: 2, c: 3 }
console.log(Object.assign({}, b, a)); // Output: { a: 1, b: 2, c: 3 }
  • 对象是保存key:value对的数据结构。
  • 对象指派会以最新的值覆写索引键。
  • 关键字b出现在多个对象中,并被其最新值覆盖。如您所见,如果您更改对象的分配/分配顺序,b值的结果值将根据具有b的最新对象而更改。

"现在让我们来看看阵列"

const c = [1,2];
const d = [2,3];

console.log([...c, ...d]); // Output: [ 1, 2, 2, 3 ]
console.log(c.concat(d)); // Output: [ 1, 2, 2, 3 ]
console.log(Object.assign({}, c, d)); // Output: { '0': 2, '1': 3 }
console.log(Object.values(Object.assign({}, c, d))); // Output: [ 2, 3 ]
  • 数组是使用Array构造函数创建的对象,该构造函数将数组作为分配给其键的值的集合输出。
  • 数组串联只是连接数组。
  • 正如上面所看到的,Object.assign仍然可以在数组上工作,因为从技术上讲,数组是一个对象,它的行为与Object.assign完全相同。在这种情况下,键就是我们在数组中所称的“索引”。这就是为什么当你执行array[index]时,它会返回值。object[key]返回一个值,用最新的值替换键/索引。
    结论:

因此,差异在于Spread运算子如何作用于对象和数组。

  • 在“对象”中,展开执行Object.assign
  • 在数组中,spread执行数组连接=〉arrayA.concat(arrayB, arrayC, ...)

奖励:设置

但是,如果希望数组只返回唯一值,则必须使用**Set**数据结构。

const c = [1,2];
const d = [2,3];

console.log([...new Set([...c, ...d])]); // Output: [1, 2, 3]
console.log(Array.from(new Set(a.concat(b)))); // Output: [1, 2, 3]

相关问题