object.assign 不能直接将数组转为纯索引对象,需配合 array.from 或 reduce:前者用 array.from 生成键值对对象再展开合并,后者通过累加器赋值更高效;直接传数组会复制 length 和方法,导致污染。

Object.assign 本身不能直接“将数组转为索引对象”,但它可以配合其他方法(如 Array.prototype.reduce 或展开运算符)实现这一目标。关键在于理解:你真正需要的,是把数组中每个元素按其下标作为键、元素值作为对应值,构造成一个普通对象(例如 {0: 'a', 1: 'b', 2: 'c'})。这种结构常用于快速按索引查值、与某些 API 兼容,或替代 Map 做轻量映射。
用 Object.assign + Array.from 构造索引对象
Array.from 可以遍历原数组,并返回新数组;配合 Object.assign,可把每个 [index, value] 转为键值对对象再合并:
const arr = ['apple', 'banana', 'cherry'];
const indexedObj = Object.assign(
{},
...Array.from(arr, (value, index) => ({ [index]: value }))
);
// → {0: "apple", 1: "banana", 2: "cherry"}
说明:Array.from 的回调返回一个个单属性对象(如 {0: 'apple'}),展开后传给 Object.assign,它会依次把它们的属性复制到空对象上。
用 Object.assign + reduce 更直观可控
reduce 更易读,也便于添加过滤或转换逻辑:
const arr = ['apple', 'banana', 'cherry'];
const indexedObj = arr.reduce((obj, value, index) => {
obj[index] = value;
return obj;
}, {});
// 等价写法(更函数式):
// const indexedObj = Object.assign({}, ...arr.map((v, i) => ({ [i]: v })));
注意:这里没用 Object.assign 在 reduce 内部做合并,因为每次赋值比新建对象更高效;若坚持用 Object.assign,可写成 Object.assign(obj, { [index]: value }),但性能略低。
注意事项:别误用 Object.assign 直接拷贝数组
以下写法不会生成索引对象,而是把数组自身当作类数组对象处理:
const arr = ['a', 'b', 'c'];
const bad = Object.assign({}, arr);
// → {0: "a", 1: "b", 2: "c", length: 3, push: f, …} ← 带了数组方法和 length!
这是因为数组是类数组对象,Object.assign 会把它的所有自有可枚举属性都复制过去。要避免污染,务必用 Array.from 或 map 显式提取键值对,不直接传数组。
补充:如果需要字符串索引或自定义键名
Object.assign 同样适用,只需在映射时调整键名:
- 按字符串数字索引:
{ ['i' + i]: v }→{i0: 'a', i1: 'b'} - 按 id 字段作键:
{ [v.id]: v }(需确保 v 有 id) - 去重合并多个数组:
Object.assign({}, ...arrays.map(a => Object.fromEntries(a.map((v,i) => [i,v]))))











