從 Compat 2021 到 Interop 2022
Compat 2021 致力於消除瀏覽器相容性問題的五個主要焦點領域,使開發者可以在這些領域上自信地建立可靠的基礎。而 Interop 2022 的重點是在15個開發者認為在不同瀏覽器之間缺失或存在相容性問題時尤其困擾的領域上制定基準。約 2216 字 (12分鐘閱讀)

陣列和物件是 JavaScript 中最常見和重要的資料結構之一。陣列提供了順序集合的功能,而物件則提供了鍵值對的功能。然而有時候,我們需要將陣列轉換為物件,以便更好地組織和處理數據。以下將介紹幾種常見的方法來實現這一轉換。
接下來將介紹下列十一種方法,從 ECMAScript 5(ES5)~ ECMAScript 2019(ES10)以及 JavaScript 的基本語法等,已知能做到將陣列轉換為物件的方法一一統整。
reduce()
forEach()
for
Loopmap()
& Object.assign()
Object.fromEntries()
for...of
reduceRight()
Array.from()
ES 版本:
reduce()
方法從 ECMAScript 5(ES5)(2009年) 開始引入。
reduce()
方法在陣列的每個元素上執行一個回調函式,將陣列轉換為一個值。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = arr.reduce((acc, curr, index) => {
acc[index] = curr;
return acc;
}, {});
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = arr.reduce((acc, curr, index, array) => {
if (index % 2 === 0) {
acc[curr] = array[index + 1];
}
return acc;
}, {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = keys.reduce((acc, curr, index) => {
acc[curr] = values[index];
return acc;
}, {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
forEach()
方法從 ECMAScript 5(ES5)(2009年) 開始引入。
forEach()
方法對陣列的每個元素執行一個回調函式。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = {};
arr.forEach((value, index) => {
obj[index] = value;
});
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = {};
let propertyName = '';
arr.forEach((value, index) => {
if (index % 2 === 0) {
propertyName = value;
} else {
obj[propertyName] = value;
}
});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = {};
keys.forEach((key, index) => {
obj[key] = values[index];
});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
for
迴圈是 JavaScript 語言的基本結構,與特定的 ES 版本無關。(嚴格來說是 ES1(1997年))
使用 for
迴圈遍歷陣列元素並建立物件。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = {};
for (let i = 0; i < arr.length; i++) {
obj[i] = arr[i];
}
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = {};
let propertyName = '';
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0) {
propertyName = arr[i];
} else {
obj[propertyName] = arr[i];
}
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = {};
for (let i = 0; i < keys.length; i++) {
obj[keys[i]] = values[i];
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
map()
方法從 ECMAScript 5(ES5)(2009年) 開始引入,Object.assign()
方法從 ECMAScript 6(ES6)(2015年) 開始引入。
map()
方法用於遍歷陣列並返回新的陣列,Object.assign()
方法用於將多個物件合併為一個新物件。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = Object.assign({}, arr.map((value, index) => ({ [index]: value })));
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = Object.assign({}, ...arr.map((value, index, array) => {
if (index % 2 !== 0) {
return { [array[index - 1]]: value };
}
}));
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = Object.assign({}, ...keys.map((key, index) => ({ [key]: values[index] })));
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
Object.fromEntries()
方法從 ECMAScript 2019(ES10)開始引入。
Object.fromEntries()
方法將包含鍵值對的陣列轉換為物件。
範例:
a. 兩層陣列
const arr = [['name', 'John'], ['age', 30], ['gender', 'male']];
const obj = Object.fromEntries(arr);
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = Object.fromEntries(
arr.reduce((entries, value, index, array) => {
if (index % 2 === 0) {
entries.push([value, array[index + 1]]);
}
return entries;
}, [])
);
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = Object.fromEntries(keys.map((key, index) => [key, values[index]]));
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:解構賦值(Destructuring Assignment)從 ECMAScript 6(ES6)開始引入,物件字面值(Object Literal)是 JavaScript 語言的基本語法,沒有特定的 ES 版本與之相關。
使用解構賦值來提取陣列的值,並結合物件字面量來建立物件。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = arr.reduce((acc, curr, index) => {
return { ...acc, [index]: curr };
}, {});
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = {};
for (let i = 0; i < arr.length; i += 2) {
const [key, value] = arr.slice(i, i + 2);
obj[key] = value;
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = keys.reduce((acc, key, index) => {
return { ...acc, [key]: values[index] };
}, {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:展開語法(Spread syntax)從 ECMAScript 6(ES6)開始引入。
使用展開語法將陣列展開,並結合物件字面量來建立物件。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = { ...arr };
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = {};
for (let i = 0; i < arr.length; i += 2) {
const [key, value] = arr.slice(i, i + 2);
obj[key] = value;
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = { ...keys.map((key, index) => ({ [key]: values[index] })) };
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
for...of
迴圈從 ECMAScript 6(ES6)開始引入。
使用 for...of
迴圈遍歷陣列元素並建立物件。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = {};
let index = 0;
for (const item of arr) {
obj[index] = item;
index++;
}
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = {};
let propertyName = '';
for (const item of arr) {
if (propertyName === '') {
propertyName = item;
} else {
obj[propertyName] = item;
propertyName = '';
}
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = {};
for (const [index, key] of keys.entries()) {
obj[key] = values[index];
}
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
reduceRight()
方法從 ECMAScript 5(ES5)(2009年) 開始引入。
reduceRight()
方法從陣列的最後一個元素開始遍歷,將每個元素與累加器結合,並返回最終的值。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = arr.reduceRight((acc, curr, index) => {
return { ...acc, [index]: curr };
}, {});
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = arr.reduceRight((acc, curr, index, array) => {
if (index % 2 === 0) {
return { ...acc, [array[index + 1]]: curr };
}
return acc;
}, {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = keys.reduceRight((acc, key, index) => {
return { ...acc, [key]: values[index] };
}, {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:
Array.from()
方法從 ECMAScript 6(ES6)開始引入。
Array.from()
方法將類陣列對象或可迭代對象轉換為真正的陣列,然後可以使用其他方法進行處理。
範例:
a. 只有一個陣列
const arr = ['apple', 'banana', 'orange'];
const obj = Array.from(arr, (value, index) => ({ [index]: value })).reduce((acc, curr) => ({ ...acc, ...curr }), {});
console.log(obj);
輸出結果:
{ 0: 'apple', 1: 'banana', 2: 'orange' }
b. 包含屬性名稱與屬性值在同一個陣列
const arr = ['name', 'John', 'age', 30, 'gender', 'male'];
const obj = Array.from(arr, (value, index, array) => {
if (index % 2 !== 0) {
return { [array[index - 1]]: value };
}
}).reduce((acc, curr) => ({ ...acc, ...curr }), {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = Array.from(keys, (key, index) => ({ [key]: values[index] })).reduce((acc, curr) => ({ ...acc, ...curr }), {});
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
ES 版本:遞迴函式的概念在 JavaScript 中是通用的,並不特定於特定的 ES 版本。
使用遞迴函式將陣列轉換為物件,並處理嵌套陣列的情況。
範例:
a. 只有一個陣列
function arrayToObject(arr) {
const obj = {};
for (let i = 0; i < arr.length; i++) {
obj[i] = arr[i];
}
return obj;
}
const arr = ['John', 30, 'male'];
const obj = arrayToObject(arr);
console.log(obj);
輸出結果:
{ 0: 'John', 1: 30, 2: 'male' }
b. 包含屬性名稱與屬性值在同一個陣列
function arrayToObject(arr) {
const obj = {};
if (Array.isArray(arr)) {
for (let i = 0; i < arr.length; i += 2) {
const key = arr[i];
const value = arr[i + 1];
if (Array.isArray(value)) {
obj[key] = arrayToObject(value);
} else {
obj[key] = value;
}
}
}
return obj;
}
const arr = ['name', 'John', 'age', 30, 'hobbies', ['reading', 'cooking']];
const obj = arrayToObject(arr);
console.log(obj);
輸出結果:
{ name: 'John', age: 30, hobbies: ['reading', 'cooking'] }
c. 兩個陣列,一個是屬性名稱,另一個是屬性值
function arrayToObject(keys, values) {
const obj = {};
for (let i = 0; i < keys.length; i++) {
obj[keys[i]] = values[i];
}
return obj;
}
const keys = ['name', 'age', 'gender'];
const values = ['John', 30, 'male'];
const obj = arrayToObject(keys, values);
console.log(obj);
輸出結果:
{ name: 'John', age: 30, gender: 'male' }
需求:讓一個陣列 ['1', '1111111'] 變成物件 { a: '1', b: '1111111'}
使用 ES6 的解構賦值(Destructuring Assignment)和物件字面值(Object Literal)的語法來將一個陣列轉換為物件。
const arr = ['1', '1111111'];
const [a, b] = arr;
const obj = { a, b };
console.log(obj);
// Output: { a: '1', b: '1111111' }
精簡後:
const arr = ['1', '1111111'];
const obj = (([a, b]) => ({ a, b }))(arr);
console.log(obj);
// Output: { a: '1', b: '1111111' }
或是使用 Object.fromEntries()
方法將由陣列組成的鍵值對列表轉換為物件。
const arr = ['1', '1111111'];
const obj = Object.fromEntries([
['a', arr[0]],
['b', arr[1]],
]);
console.log(obj);
// Output: { a: '1', b: '1111111' }
而關於這兩種哪一種比較好呢?
這兩種方法都可以將陣列轉換為物件,取決於個人偏好和程式碼的可讀性。
第一種方法使用解構賦值和物件字面值簡化的語法,可以在一行內完成操作。這種寫法相對緊湊,對於熟悉這種語法的開發者來說可能更直觀。
第二種方法使用 Object.fromEntries()
方法將由陣列組成的鍵值對列表轉換為物件。這種寫法明確地將每個鍵值對指定為獨立的元素,可能更易於理解。
在選擇使用哪種方法時,可以考慮以下因素:
總之這兩種方法都是有效的,具體選擇取決於對語法的舒適度和代碼的可讀性需求。
每種方法都有其優點和用途,取決於需求和程式碼的上下文。
[1] JavaScript Versions
https://www.w3schools.com/js/js_versions.asp
[2] MDN Web Docs
將陣列 (Array) 轉換為物件 (Object)
作者
約 2216 字 (12分鐘閱讀)
約 2161 字 (11分鐘閱讀)
約 1851 字 (10分鐘閱讀)