「配列の中身を処理するのに、いつも$.each()使ってるけど、他の方法があるって聞いた…」 「mapとかfilterとか出てくるけど、どう使い分ければいいの?」 「そもそもこれらの新しいメソッドって、どんなメリットがあるの?」
前回は変数宣言のlet/constについて解説しました。今回は、jQueryの$.each()
から、モダンJavaScriptの配列メソッドへの移行を見ていきましょう。これらのメソッドを使いこなすことで、より意図が明確で保守性の高いコードが書けるようになります。
なぜ$.each()から移行するのか?
まずは従来のjQueryでの配列操作を見てみましょう:
JS
// jQueryでの配列操作
var users = [
{ id: 1, name: "John", age: 25 },
{ id: 2, name: "Jane", age: 30 },
{ id: 3, name: "Bob", age: 20 }
];
// 名前の配列を作成
var names = [];
$.each(users, function(index, user) {
names.push(user.name);
});
// 20歳以上のユーザーを抽出
var adults = [];
$.each(users, function(index, user) {
if (user.age >= 20) {
adults.push(user);
}
});
// 年齢の合計を計算
var totalAge = 0;
$.each(users, function(index, user) {
totalAge += user.age;
});
このコードには以下の問題があります:
- 中間配列の作成が必要
- 処理の意図が分かりにくい
- チェーンが困難
- 余分なインデックス引数
モダンな配列メソッドの基本
JavaScriptには、目的に応じた様々な配列メソッドが用意されています:
JS
const users = [
{ id: 1, name: "John", age: 25 },
{ id: 2, name: "Jane", age: 30 },
{ id: 3, name: "Bob", age: 20 }
];
// map: 配列の各要素を変換
const names = users.map(user => user.name);
// filter: 条件に合う要素を抽出
const adults = users.filter(user => user.age >= 20);
// reduce: 値を集約
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
主要な配列メソッドの使い分け
1.map(): 変換
JS
// Before: jQuery
var prices = [];
$.each(products, function(index, product) {
prices.push(product.price);
});
// After: Modern JavaScript
const prices = products.map(product => product.price);
2.filter(): 抽出
JS
// Before: jQuery
var activeUsers = [];
$.each(users, function(index, user) {
if (user.isActive) {
activeUsers.push(user);
}
});
// After: Modern JavaScript
const activeUsers = users.filter(user => user.isActive);
3.reduce(): 集約
JS
// Before: jQuery
var total = 0;
$.each(items, function(index, item) {
total += item.quantity * item.price;
});
// After: Modern JavaScript
const total = items.reduce(
(sum, item) => sum + item.quantity * item.price,
0
);
4.find(): 要素の検索
JS
// Before: jQuery
var targetUser = null;
$.each(users, function(index, user) {
if (user.id === targetId) {
targetUser = user;
return false; // ループを抜ける
}
});
// After: Modern JavaScript
const targetUser = users.find(user => user.id === targetId);
メソッドチェーンで処理を組み合わせる
モダンな配列メソッドの大きな特徴は、チェーンで処理を組み合わせられることです:
JS
const result = users
.filter(user => user.age >= 20)
.map(user => ({
fullName: `${user.firstName} ${user.lastName}`,
age: user.age
}))
.sort((a, b) => a.age - b.age);
実践的なリファクタリング例
実際のjQueryコードをモダンな書き方に変更してみましょう:
JS
// Before: jQuery
var $userList = $('#userList');
var activeUsers = [];
$.each(users, function(index, user) {
if (user.isActive) {
activeUsers.push(user);
}
});
$.each(activeUsers, function(index, user) {
var $li = $('<li>')
.addClass('user-item')
.text(user.name);
$userList.append($li);
});
// After: Modern JavaScript
const userList = document.querySelector('#userList');
const activeUsers = users
.filter(user => user.isActive)
.map(user => `<li class="user-item">${user.name}</li>`)
.join('');
userList.innerHTML = activeUsers;
パフォーマンスと注意点
1.早期リターン
JS
// findは条件に合致したら処理を停止
const user = users.find(user => user.id === targetId);
// someは存在確認に最適
const hasAdmin = users.some(user => user.role === 'admin');
2.不要なチェーンを避ける
JS
// Bad: 無駄な中間配列が作られる
const result = users
.map(user => user.age)
.filter(age => age >= 20)
.map(age => age * 2);
// Good: 1回のループで処理
const result = users
.reduce((acc, user) => {
if (user.age >= 20) {
acc.push(user.age * 2);
}
return acc;
}, []);
まとめ
モダンな配列メソッドを使うことで:
- コードの意図がより明確に
- 中間変数が不要に
- 処理の組み合わせが容易に
- メンテナンス性が向上
という効果が得られます。次回は「テンプレートリテラルでHTML生成を最適化」について解説し、さらに表現力豊かなコードの書き方を学んでいきましょう。