BMI で体型を判定する
BMI で体型を判定する とは
身長と体重から BMI を計算し、痩せ / 標準 / 肥満 を返す関数を書く。本レッスンでは、BMI で体型を判定する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
BMI で体型を判定する
ここまでで if / else else if switch guard clause という分岐の道具を一通り見てきました。このレッスンでは、それを 応用 して「身長と体重から BMI を計算し、結果を 3 段階で判定する」という実用的な問題を解きます。条件分岐は単独で使うことよりも、計算や入力チェックと組み合わせて使うことのほうが圧倒的に多いです。
BMI は
Body Mass Indexの略で、体重 (kg) ÷ (身長 (m))^2で求めます。日本肥満学会の基準では、18.5未満を「低体重 (やせ)」、18.5以上25.0未満を「普通体重」、25.0以上を「肥満」と分類するのが一般的です。
計算式と判定基準
身長は cm ではなく m に直す必要があります。170 cm なら 1.7 m です。/ で割って、二乗は ** 演算子か Math.pow を使います。
JavaScript
const heightM = 170 / 100;
const weightKg = 65;
const bmi = weightKg / (heightM ** 2); // 22.49...判定基準は次の通りです。
bmiが18.5未満 →'やせ'18.5以上25.0未満 →'標準'25.0以上 →'肥満'
境界値 18.5 ちょうどは「標準」側、25.0 ちょうどは「肥満」側に含めるのがポイントです。
動きを追ってみる
身長 170 cm、体重 65 kg の人を例にコードを組み立てると次のとおりです。
JavaScript
function bmiLabel (heightCm, weightKg) {
const heightM = heightCm / 100;
const bmi = weightKg / (heightM ** 2);
if (bmi < 18.5) {
return 'やせ';
} else if (bmi < 25.0) {
return '標準';
} else {
return '肥満';
}
}
bmiLabel(170, 65); // '標準'
bmiLabel(170, 50); // 'やせ'
bmiLabel(170, 90); // '肥満'途中で bmi を変数に取り出している点に注目してください。if の条件式に weightKg / (heightCm / 100) ** 2 < 18.5 のように直接書いてしまうと、計算ミスや優先順位ミスが起きやすくなります。中間値は名前を付けた変数に入れる のがコツです。
図で見ると、計算と分岐がきれいに分離しています。実務でも「計算 → 結果に名前を付ける → 分岐」と段階的に書くと、後からデバッグしやすくなります。
「先に式を組み立ててから条件を書く」という順番を意識すると、
ifの条件は単純な比較だけになり、読み手の負担がぐっと減ります。
境界値テストの大切さ
このような 段階的な判定 を書いたら、必ず 境界値 をテストしましょう。境界値は次の通りです。
bmiがちょうど18.5→ 標準bmiがちょうど25.0→ 肥満
境界値の判定は、
<<=>>=のいずれを使うかで結果が変わります。ここを<=と<でうっかり混ぜると、ちょうど25.0のときに「標準」と「肥満」の両方に当てはまる、もしくはどちらにも当てはまらないバグが入ります。
例として身長 200 cm、体重 100 kg のとき bmi はちょうど 25.0 です。判定は「肥満」が正解です。
身長と体重の組み合わせによっては、浮動小数点の誤差で計算結果がわずかにズレることもあります。境界ピッタリの値が必要なときは、計算しやすい組み合わせ (身長 200 cm など) を選ぶか、Math.round で丸めるという手もあります。
よくある間違い
- 身長を
cmのまま計算する。bmi = 65 / (170 ** 2)のように書くと、0.00225...という意味不明な値になります。mに直すのを忘れないようにします。 - 境界値の
<と<=を間違える。if (bmi <= 18.5) return 'やせ';と書くと、ちょうど18.5のときが「やせ」になってしまいます。 - 計算を
ifの中に押し込む。可読性が落ちる上に、同じ計算を何度も書くことになります。const bmi = ...;で一度名前を付けてから使いましょう。
やってみよう
身長 heightCm (cm 単位の数値) と体重 weightKg (kg 単位の数値) を受け取り、BMI に応じて 'やせ' '標準' '肥満' のいずれかを返す関数 bmiLabel を実装してください。bmi が 18.5 ちょうどは '標準'、25.0 ちょうどは '肥満' に分類します。
よくある質問
Q. ブラウザと Node.js で動作は変わりますか?
A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。
Q. ES6 以降の新機能は使っても大丈夫ですか?
A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。
Q. TypeScript に進む価値はありますか?
A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。
次のレッスン
次は FizzBuzz で複数条件を組み立てる で、身長と体重から BMI を計算し、痩せ / 標準 / 肥満 を返す関数を書く を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- BMI 判定 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. BMI 判定 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 身長を cm から m に変換してから BMI を計算すること
- if / else if を使って 3 段階に判定すること
- 境界値の取り扱い (18.5 は標準、25.0 は肥満) を守ること
入出力例
test-cases.txt
bmiLabel(170, 65) → "標準"
bmiLabel(170, 50) → "やせ"
bmiLabel(170, 90) → "肥満"
bmiLabel(200, 100) → "肥満"
bmiLabel(200, 74) → "標準"
bmiLabel(150, 40) → "やせ"