JavaScriptの偉大さに気づいた新卒未経験エンジニア
2025年に新卒で入社したMJです。
好きな食べ物はカレーです。
研修を通してさまざまな技術に触れる中で、「これって本当に必要なの?」と感じた技術がありました。それがJavaScriptです。
右も左もわからない状態だった私は、「全部Javaで書けばいいじゃん」と思っていました。
しかし、それが大きな間違いだと気づいたのが、研修の集大成となる個人開発のときです。
検索機能を実装する際に、JavaScriptの真価を実感しました。
その体験を語る前に、まずはJavaScriptについて簡単におさらいします。
1. JavaScriptとは?
JavaScriptは、Webページに動的な機能を追加するためのプログラミング言語です。
JavaScriptの特徴
1. クライアントサイドで動作
- ブラウザ上で直接動作し、Webページにインタラクティブな機能(アニメーション、入力チェック、ボタンの動作など)を追加できる。
- サーバーとの通信をせずにユーザーの操作に即時に反応できる。
2. オブジェクト指向・関数型の両方をサポート
- オブジェクトを使った設計も、関数を使った柔軟なプログラミングも可能。
- クラス(class)や継承、クロージャ、コールバック、ラムダ式(アロー関数)などもサポートしている。
3. 非同期処理が得意
- Promiseやasync/awaitを使った非同期処理が簡単に書ける。
- サーバーとの通信(API呼び出し)などでよく使われる。
4. マルチプラットフォーム対応
- ブラウザだけでなく、Node.jsを使えばサーバーサイドのプログラムも書ける。
- デスクトップアプリ(Electron)やモバイルアプリ(React Native)にも応用可能。
5. 豊富なライブラリとフレームワーク
- フロントエンド: React, Vue.js, Angularなど。
- サーバーサイド: Express.js など。
JavaScriptでできること
- ボタンを押したときにメッセージを表示
- 入力フォームのチェック(バリデーション)
- スライドショーやアニメーション
- Webページの一部を動的に書き換える(例:Ajax)
- サーバーと通信してデータを取得(例:fetch API)
- ゲームやインタラクティブなUIの作成
2. MJがJavaScriptの魅力に惹かれた理由
検索機能を初めて実装したとき、最低限の動作はしていたものの、使い心地はあまり良くありませんでした。
そこで、他のサイトを参考にしたり、欲しい機能の実装方法を調べたりする中で、JavaScriptの必要性を痛感しました。
例えば、リアルタイム検索の爽快感です。
JavaScriptを使うことで、ユーザーが文字を入力するたびに検索結果を即座に表示できるようになりました。
ページをリロードする必要もなく、スムーズに結果が変化するこの体験を自分で作れたことは衝撃的でした。
さらに、APIからデータを取得する非同期処理も、async/await を使うことで驚くほどシンプルに書くことができました。
待ち時間が発生しても、画面が固まることなくユーザーは快適に操作を続けられます。
この経験を通じて、私はJavaScriptの偉大さとWeb開発における重要性を認識することができました。
実際のコードの一部を紹介します。以下のようにして、検索機能やページネーションを実現しました。
3. 初期データの取得
最初のページ表示時、JavaScriptでAPIから総件数と初期データを取得し、表示を行っています。
async function fetchTotalCount() {
const response = await fetch('/BKN003/count');
if (!response.ok) throw new Error('総件数取得失敗');
return await response.json();
}
async function fetchAndDisplayAll(page, size) {
try {
const response = await fetch(`/BKN003/init?page=${page}&size=${size}`);
if (!response.ok) throw new Error('データ取得失敗');
const results = await response.json();
displayResults(results);
renderPagination(totalCount, page, size);
window.scrollTo({ top: 0, behavior: 'smooth' });
} catch (err) {
alert('データの取得に失敗しました');
console.error(err);
}
}
try {
totalCount = await fetchTotalCount();
await fetchAndDisplayAll(currentPage, pageSize);
} catch (e) {
alert('初期化に失敗しました');
console.error(e);
}
4. 検索処理
ユーザーが入力した条件でAPIにリクエストを送り、該当データを取得する処理です。
form.addEventListener('submit', async function (e) {
e.preventDefault();
const name = document.getElementById('name').value.trim();
const seasonId = document.getElementById('seasonId').value.trim();
if (!name && !seasonId) {
alert('選手名またはシーズンIDのいずれかを入力してください。');
return;
}
if (seasonId && !/^\d{4}$/.test(seasonId)) {
alert('シーズンIDは4桁の数字で入力してください。');
return;
}
try {
const response = await fetch('/BKN003/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, seasonId })
});
if (!response.ok) throw new Error('検索失敗');
const results = await response.json();
displayResults(results);
paginationContainer.innerHTML = '';
topPaginationContainer.innerHTML = '';
} catch (err) {
alert('検索に失敗しました');
console.error(err);
}
});
5. ページネーション処理
データ件数に応じてページ送りボタンを生成し、指定ページのデータを再取得します。
function renderPagination(totalCount, page, size) {
const totalPages = Math.ceil(totalCount / size);
const maxPageButtons = 10;
let startPage = Math.max(1, page - Math.floor(maxPageButtons / 2));
let endPage = startPage + maxPageButtons - 1;
if (endPage > totalPages) {
endPage = totalPages;
startPage = Math.max(1, endPage - maxPageButtons + 1);
}
function createButtons(container) {
container.innerHTML = '';
const prevBtn = document.createElement('button');
prevBtn.textContent = '前へ';
prevBtn.className = 'white-button';
prevBtn.disabled = (page === 1);
prevBtn.onclick = () => {
if (page > 1) {
currentPage = page - 1;
fetchAndDisplayAll(currentPage, pageSize);
}
};
container.appendChild(prevBtn);
for (let i = startPage; i <= endPage; i++) {
const pageBtn = document.createElement('button');
pageBtn.textContent = i;
pageBtn.className = 'white-button';
if (i === page) {
pageBtn.style.fontWeight = 'bold';
pageBtn.style.backgroundColor = '#ddd';
pageBtn.disabled = true;
}
pageBtn.onclick = () => {
currentPage = i;
fetchAndDisplayAll(currentPage, pageSize);
};
container.appendChild(pageBtn);
}
const nextBtn = document.createElement('button');
nextBtn.textContent = '次へ';
nextBtn.className = 'white-button';
nextBtn.disabled = (page === totalPages);
nextBtn.onclick = () => {
if (page < totalPages) {
currentPage = page + 1;
fetchAndDisplayAll(currentPage, pageSize);
}
};
container.appendChild(nextBtn);
}
createButtons(topPaginationContainer);
createButtons(paginationContainer);
}
6. 最後に
3か月の研修期間を終え、いよいよ実際の現場で働くことになります。
研修の初めはわからないことだらけでとても大変でしたが、できることが増え、エラーを解決したり便利な構文を見つけたりするうちに、プログラミングの楽しさがわかるようになりました。
これからは、仕事をこなしながら新たな技術や資格の習得に積極的に取り組んでいきます。