一覧へ

JavaScriptで実験データを扱う

実験データをJavaScriptで処理する方法。変数、条件分岐、ループ、関数をバイオの例で学びます。

入門
|
90
|
検証済み (2026-06)
JavaScript変数条件分岐ループ関数実験データ処理
進捗0/19 (0%)

JavaScriptで実験データを扱う

前回HTML/CSSで実験プロトコルのWebページを作りました。きれいですが、そのページはゲル画像の「写真」のようなもの — 見ることはできますが、反応しません。

JavaScriptを加えるとWebページが生き生きと動きます。OD値を入力すると自動で濃度を計算し、力価が基準値以下なら警告を出し、96サンプルの結果を一括処理できます。HTMLがゲル画像なら、JavaScriptはその画像を分析するImageJソフトウェアです。

変数:実験ノートにデータを記録する

変数(variable)はデータにラベルを付けて保存することです。実験ノートに「サンプル濃度:2.5 μg/mL」と書き留めるのと同じです。

javascript
const geneName = "BRCA1";
const sampleConcentration = 2.5;
let experimentStatus = "進行中";

console.log(geneName);            // "BRCA1"
console.log(sampleConcentration); // 2.5
console.log(experimentStatus);    // "進行中"

constは変わらない値に、letは変わる可能性のある値に使います。遺伝子名は実験中に変わらないのでconst、実験ステータスは「進行中」から「完了」に変わるのでletです。

JavaScriptには3つの基本データ型があります:

javascript
// 文字列(String)— 遺伝子名、サンプルラベル
const proteinTarget = "EGFR";

// 数値(Number)— 濃度、OD値、温度
const reactionTemp = 37;
const odValue = 0.85;

// ブーリアン(Boolean)— 真偽判定
const isPositive = true;
const hasContamination = false;

console.log(typeof proteinTarget); // "string"
console.log(typeof reactionTemp);  // "number"
console.log(typeof isPositive);    // "boolean"

文字列は引用符で、数値はそのまま、ブーリアンはtrue/falseで書きます。PCR結果が陽性か陰性か — ちょうど2つの状態だけが存在するのがブーリアンです。

条件分岐:実験結果を判定する

条件分岐(conditional)は「バンドがあれば陽性、なければ陰性」のように状況に応じて異なるアクションをするロジックです。実験で毎日行う意思決定をコードに変換したものです。

javascript
const ctValue = 28.5;
const threshold = 35;

if (ctValue < threshold) {
  console.log("陽性(Positive)");
} else {
  console.log("陰性(Negative)");
}
// 出力: "陽性(Positive)"

console.assert(ctValue < threshold, "Ct 28.5はthreshold 35未満");

条件が複数ある場合はelse ifを使います:

javascript
const purityRatio = 1.95;

let qualityGrade;
if (purityRatio >= 1.8 && purityRatio <= 2.0) {
  qualityGrade = "純粋DNA";
} else if (purityRatio < 1.8) {
  qualityGrade = "タンパク質汚染の疑い";
} else {
  qualityGrade = "RNA汚染の疑い";
}

console.log(`A260/A280 = ${purityRatio} → ${qualityGrade}`);
// 出力: "A260/A280 = 1.95 → 純粋DNA"

console.assert(qualityGrade === "純粋DNA");

ここで===は「正確に同じか?」を比較する演算子です。=(値を入れること)と混同しないでください。実験で「濃度を設定すること」と「濃度を測定して確認すること」は全く異なる行為です。代入は=、比較は===です。

配列とループ:サンプルリストの一括処理

配列(array)は複数のデータを順番に入れる箱です。ゲル上のバンドを左から順に並べたものと同じです。

javascript
const sampleIds = ["S001", "S002", "S003", "S004", "S005"];
const odValues = [0.45, 1.23, 0.89, 0.12, 2.15];

console.log(sampleIds[0]);     // "S001"(最初)
console.log(sampleIds.length); // 5(総数)
console.log(odValues[2]);      // 0.89(3番目)

配列のインデックスは0から始まります。96ウェルプレートでA1が0番目のウェルであるのと同じです。

ループ(loop)は96ウェルプレートの全ウェルに同じ処理を施すことです。サンプルが5個でも500個でも、コード1つで全部処理できます。

javascript
const geneList = ["TP53", "BRCA1", "EGFR", "KRAS", "MYC"];

for (let i = 0; i < geneList.length; i++) {
  console.log(`分析対象 ${i + 1}: ${geneList[i]}`);
}
// 分析対象 1: TP53
// 分析対象 2: BRCA1
// 分析対象 3: EGFR
// 分析対象 4: KRAS
// 分析対象 5: MYC

console.assert(geneList.length === 5, "遺伝子リストは5個");

forループは3つの部分で構成されます:開始値(let i = 0)、繰り返し条件(i < geneList.length)、増加式(i++)。毎回iが1ずつ増えながら、配列の最初から最後まで巡回します。

配列と条件分岐を組み合わせれば、大量サンプルのQC判定も自動化されます:

javascript
const samples = ["S001", "S002", "S003", "S004"];
const concentrations = [2.5, 0.3, 1.8, 0.1];
const minConcentration = 0.5;

let passCount = 0;
for (let i = 0; i < samples.length; i++) {
  if (concentrations[i] >= minConcentration) {
    console.log(`${samples[i]}: PASS`);
    passCount++;
  } else {
    console.log(`${samples[i]}: FAIL(再抽出必要)`);
  }
}
console.log(`合格: ${passCount}/${samples.length}`);
// S001: PASS
// S002: FAIL(再抽出必要)
// S003: PASS
// S004: FAIL(再抽出必要)
// 合格: 2/4

console.assert(passCount === 2, "0.5以上のサンプルは2個");

条件分岐1つ、ループ1つで手動QCチェックが自動化されました。サンプルが100個に増えてもコードはそのままです。

関数:プロトコルを再利用可能にする

関数(function)は実験プロトコルの1ステップを再利用可能にパッケージしたものです。「GC含量計算」というプロトコルを一度定義しておけば、どんな配列でも入れれば結果が出ます。

javascript
function calculateGcContent(sequence) {
  let gcCount = 0;
  for (let i = 0; i < sequence.length; i++) {
    if (sequence[i] === "G" || sequence[i] === "C") {
      gcCount++;
    }
  }
  return (gcCount / sequence.length) * 100;
}

const gc1 = calculateGcContent("ATGCGATCGA");
const gc2 = calculateGcContent("AAATTTAAATTT");

console.log(`ATGCGATCGA → GC = ${gc1}%`);   // 50%
console.log(`AAATTTAAATTT → GC = ${gc2}%`);  // 0%

console.assert(gc1 === 50, "ATGCGATCGAのGC含量は50%");
console.assert(gc2 === 0, "AAATTTAAATTTのGC含量は0%");

関数の構成要素:

  • function calculateGcContent(sequence) — 関数名とパラメータ(parameter):プロトコル名と「何を入れるか」
  • { ... }の中のコード — プロトコルの実際の手順
  • return — 結果を返すこと。実験が終わってデータを報告するステップ
  • calculateGcContent("ATGCGATCGA") — 関数呼び出し。パラメータの位置に入れる実際の値を**引数(argument)**と呼びます

希釈計算も関数にできます:

javascript
function dilutionVolume(stockConc, finalConc, finalVol) {
  return (finalConc * finalVol) / stockConc;
}

const needed = dilutionVolume(10, 1, 500);
console.log(`原液 ${needed} μL 必要`); // 原液 50 μL 必要

console.assert(needed === 50, "C1V1 = C2V2 検証");

一度関数を作っておけば、濃度が変わっても数値を変えるだけです。毎回電卓を叩くよりずっと速くミスもありません。

やってみよう(Faded Example)

空欄を埋めてDNA配列のGC含量判定コードを完成させてください。

穴埋め問題javascript
const sequence = "ATGCGCTA";
const gcThreshold = 40;
let gcCount = 0;
for (let i = 0; i < sequence.; i++) {
if (sequence[i] === "G" || sequence[i] === "") {
gcCount++;
}
}
const gcPercent = (gcCount / sequence.length) * ;
if (gcPercent >= gcThreshold) {
console.log("High GC");
} else {
console.log("Low GC");
}

よくあるエラーと解決法

Q: ====を混同します

=は値を入れること(代入)、===は同じかどうか比較することです。if (status = "pass")と書くと比較ではなく代入になり、常にtrueになります。条件分岐の中では必ず===を使ってください。

Q: 配列の最後の要素にアクセスするには?

const genes = ["TP53", "BRCA1", "EGFR"]genes[3]undefinedです。配列インデックスは0から始まるので、最後の要素はgenes[genes.length - 1]でアクセスします。

Q: constで宣言した変数を変更しようとするとエラーが出ます

TypeError: Assignment to constant variable.constは一度決めた値を変更できません。値が変わる必要がある変数はletで宣言してください。

Q: 関数を呼び出したのにundefinedが返ってきます

関数内にreturnがないと結果を返しません。console.log()は画面に出力するだけで値を返しません。計算結果を他で使う必要があるなら必ずreturnを入れてください。

Q: 講義でvarを使っているコードがありますが、let/constと何が違いますか?

varはES6(2015)以前の古い宣言方法で、関数スコープです。let/constブロックスコープ{}の中だけで有効です。varはブロックを無視して外からもアクセスできるため、予期しないバグを生みます:

javascript
if (true) {
  var x = 10;
  let y = 20;
}
console.log(x); // 10(外からアクセスできてしまう)
// console.log(y); // ReferenceError(ブロック外なのでアクセス不可)

古い講座でvarを使っているのは講座の時点がES6以前だからです。現代のJavaScriptでは基本的にconst、値が変わる必要がある時だけletを使ってください。varは使わないでください。

Q: ? :は何ですか?(三項演算子)

条件 ? 値1 : 値2 — 条件がtrueなら値1、falseなら値2を返す演算子です。if/elseを1行に圧縮したものです:

javascript
const od = 1.85;
const result = od >= 1.0 ? "pass" : "fail";
// if (od >= 1.0) { result = "pass" } else { result = "fail" } と同じ

Q: !はどういう意味ですか?

!は論理否定(NOT)演算子です。truefalseに、falsetrueに反転します:

javascript
const hasPermission = false;
if (!hasPermission) {
  console.log("アクセス拒否"); // これが実行される
}

!変数名は「変数がfalseなら」と読めばよいです。!isPassedは「合格していなければ」。

Q: DOMとは何ですか?document.getElementByIdはどこから来たのですか?

DOM(Document Object Model)はブラウザがHTMLを読んでJavaScriptで操作できるツリー構造のオブジェクトに変換したものです。documentはそのツリーの頂点で、getElementById()はツリーから特定の要素を見つけるメソッドです:

javascript
// HTML: <div id="result">待機中</div>
const resultDiv = document.getElementById("result");
resultDiv.innerText = "分析完了!";

HTMLが「設計図」なら、DOMはブラウザがその設計図で建てた「建物」です。JavaScriptはこの建物の壁を塗ったり家具を動かしたりできます。

Q: バックティック(`)は引用符と何が違いますか?

バックティックはテンプレートリテラルを作る文法です。文字列の中に${変数名}で値を直接挿入できます:

javascript
const gene = "TP53";
const od = 2.15;

// 引用符:文字列結合が面倒
const msg1 = gene + "のOD値: " + od;

// バックティック:きれいに挿入
const msg2 = `${gene}のOD値: ${od}`;

// 計算式も可能
const msg3 = `30日 = ${60 * 60 * 24 * 30}秒`;

シングルクオート(')やダブルクオート(")で書くと${}がそのまま文字として出力されます。必ずバックティック(`)を使ってください。

Q: 式(expression)と文(statement)とは何ですか?

は値に評価されるコードです — 変数に格納できます。は動作するだけで値を生みません:

javascript
// 式:値になる
1 + 1            // 2
od >= 1.0        // true
"pass"           // "pass"

// 文:動作するだけ(値にならない)
if (true) { }    // 条件分岐
for (let i...) { } // ループ

関数もreturnがあれば呼び出し結果が値(式)になり、returnがなければundefinedを返します。先ほどの「関数を呼び出したのにundefinedが返ってきます」のQ&Aとつながる概念です。

Q: アロー関数(arrow function)=>とは何ですか?

functionキーワードの代わりに=>で関数を短く書く文法です。コールバック関数でよく使います:

javascript
// 従来の方式
samples.filter(function(s) {
  return s.status === "pass";
});

// アロー関数方式 — 同じ動作
samples.filter((s) => {
  return s.status === "pass";
});

// さらに短く — 本文が1行なら中括弧とreturnを省略可能
samples.filter(s => s.status === "pass");

function(x) { return ... }x => ...はほとんどの場合同じ動作をします。DevBenchでは初心者が読みやすいfunction方式を使いますが、実務コードやAIが生成するコードではアロー関数が圧倒的に多く使われます。

Q: JavaScriptでエラーが出るとなぜ全体が止まるのですか?

JavaScriptはコードを上から順番に実行します。途中でエラーが発生するとその行で止まり、下のコードは実行されません:

javascript
console.log("1番目は出力される");
console.log("Hello".indexOf);  // エラー発生箇所
console.log("3番目は出力されない"); // 実行されない

そのためConsoleにエラーが出たら、エラーメッセージの行番号を先に確認してその行を修正してください。下のコードが動かないのは下の問題ではなく、上のエラーのせいです。

Q: 主要な演算子を一覧で見たいです

種類演算子意味結果
算術+ - * / %足す、引く、掛ける、割る、余り5 % 21
比較=== !== > <等しい(型含む)、等しくない、大きい、小さい5 === "5"false
論理&& || !AND、OR、NOT!truefalse
代入= += -=代入、加算代入、減算代入x += 3x = x + 3
その他typeof ? :型確認、三項演算子typeof 42"number"

比較演算子で==(緩い比較)と===(厳密な比較)の違いを覚えてください。5 == "5"trueですが5 === "5"falseです。実務では常に===を使うのが安全です。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...