JavaScriptの壁
JavaScriptを書き始めてしばらく経った頃、こんな壁にぶつかることはありませんか?
-
「なんとなく動くコード」は書けるけど、もっと効率的に書きたい
-
可読性の高いコードにしたいけど、どこから手をつければいいか分からない
-
チーム開発で求められる“中級者レベル”のスキルって何?
本記事では、そんな疑問を抱えるあなたに向けて、実務で本当に役立つ“中級者向けJavaScriptテクニック”を10個厳選してお届けします。
すべて実際に試せるコード付きで、「なるほど、こうすれば良かったのか!」と思える内容にしています。
実務で差がつく!中級者向けJavaScriptテクニック10選
1. 分割代入でコードを簡潔に
// Before
const name = user.name;
const age = user.age;
// After
const { name, age } = user;
オブジェクトからプロパティを取り出すとき、分割代入(Destructuring)を使えば、読みやすくミスも減ります。
2. Nullish Coalescingで安全な値処理
const displayName = user.name ?? '匿名ユーザー';
|| と違って null や undefined のみを対象にするため、0や空文字を誤って判定することがありません。
3. Optional Chainingでネストの深い値も安全にアクセス
const zipcode = user?.address?.zipcode;
ネストが深いオブジェクトのアクセスでもエラーを防げます。
4. アロー関数とthisの扱い
// 通常の関数(thisが変わる)
setTimeout(function() {
console.log(this); // Window
}, 1000);
// アロー関数(thisがレキシカル)
setTimeout(() => {
console.log(this); // 外側のthisを保持
}, 1000);
thisの扱いで混乱したことはありませんか?アロー関数はthisが固定されるので、イベントや非同期処理でも使いやすいです。
5. スプレッド構文の活用
const arr1 = [1, 2];
const arr2 = [3, 4];
const all = [...arr1, ...arr2]; // [1,2,3,4]
配列の結合やオブジェクトのコピーが簡単になります。
6. テンプレートリテラルで可読性向上
const message = `こんにちは、${user.name}さん!`;
複雑な文字列連結もテンプレートリテラルでシンプルに。
7. 高階関数(map/filter/reduce)の使いこなし
const prices = [100, 200, 300];
const withTax = prices.map(p => p * 1.1);
関数型プログラミングの第一歩。業務のデータ整形にも頻出します。
8. 非同期処理はasync/awaitでスッキリ
async function fetchData() {
const res = await fetch('/api/data');
const data = await res.json();
console.log(data);
}
async と await は、JavaScriptにおける非同期処理をより直感的に書くための構文です。
-
async は関数を非同期関数として定義するためのキーワードです。この関数は常に Promise を返します。
-
await は、async 関数の中で使い、Promiseの完了を待つ構文です。
これにより、非同期処理を同期処理のように記述でき、ネストが深くなりがちな Promise.then() チェーンよりも読みやすく、エラーハンドリングもしやすいコードが書けます。
9. イミュータブルな配列操作
const newList = [...oldList, newItem];
状態管理では「元の配列を壊さない」書き方が求められます。
10. クリーンコードの意識(関数分割・命名)
function calcTax(price) {
return price * 1.1;
}
function showPriceWithTax(price) {
const taxed = calcTax(price);
console.log(`税込価格は${taxed}円です。`);
}
ひとつの関数に複数の責任を持たせず、意図が明確になるよう分割するのがポイントです。
よくある落とし穴と改善ポイント
落とし穴1:undefinedのまま操作してエラー
// NG
const len = user.name.length; // nameがundefinedだとエラー
// OK
const len = user.name?.length;
Optional Chainingが活きるポイントです。
ただし、Optional Chainingにも注意点があります。
-
存在しないプロパティを参照してもエラーが出ないため、不具合の発見が遅れる可能性があります。
-
連鎖的に使用しすぎると、コードの意図が不明瞭になることがあります。
-
曖昧な設計のままでもコードが通ってしまうため、適切なバリデーションを省略しがちです。
あくまで「安全にアクセスする補助的な手段」として使い、必要なバリデーションやチェック処理と併用するのがベストです。
落とし穴2:thisの誤解
const obj = {
value: 42,
logValue: function() {
setTimeout(function() {
console.log(this.value); // undefined
}, 1000);
}
};
この場合、普通のfunctionは別スコープのthisになるため注意が必要です。
→ アロー関数で回避可能!
落とし穴3:forEachで非同期処理しない
// NG
items.forEach(async item => {
await doSomething(item); // 動かない
});
// OK
for (const item of items) {
await doSomething(item);
}
forEachは非同期の処理に向いていません。素直にfor…ofを使いましょう。
次に学ぶべきステップと実務への応用
今回紹介したテクニックは、すべて現場で役立つものばかりです。特にチーム開発では「読みやすさ」「保守性」が大切です。
【外部リンク】
MDN Web Docs: Destructuring assignment
MDN Web Docs: Nullish coalescing operator (??)
MDN Web Docs: Optional chaining (?.)
MDN Web Docs: Template literals
MDN Web Docs: Array.prototype.map()
【内部リンク】
JavaScriptでよく発生するエラー「ReferenceError」「SyntaxError」などの原因と対策を具体例付きで解説