這一課完成後:你會分清楚原始碼、執行環境與輸出,知道為什麼同一個檔案需要某個程式來讀它,也能第一次自己修改程式並觀察結果。

先做:建立第一個真的會執行的檔案

打開你的 norelyn-first-project。在專案根目錄建立:

run.html

把下面內容完整貼進去並儲存:

<!doctype html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8">
  <title>First Run</title>
</head>
<body>
  <h1 id="output">還沒執行</h1>

  <script>
    const message = "Hello, Norelyn Learn.";
    document.querySelector("#output").textContent = message;
  </script>
</body>
</html>

現在從檔案管理器雙擊 run.html,讓它在瀏覽器中打開。

如果一切正常,畫面不會停在「還沒執行」,而會變成:

Hello, Norelyn Learn.

你剛才已經執行了一個程式。

剛才到底發生了什麼?

run.html 本身只是一個存在硬碟上的文字檔。它不會因為裡面有 JavaScript 就自己啟動。

真正發生的是:

run.html → 瀏覽器讀取 → JavaScript 引擎執行 → 畫面被修改

瀏覽器在這裡不只是「顯示網頁的 App」。它也提供了能理解 HTML、CSS、JavaScript 的執行環境。

Source code:你寫下來的是原始碼

你剛才在 VS Code 裡看到的:

const message = "Hello, Norelyn Learn.";

是 source code,也就是原始碼。它是寫給程式語言工具處理的文字,同時也盡量讓人能閱讀與修改。

但「原始碼存在」和「程式正在執行」是兩件不同的事。

一個 .js 檔案不等於一個正在跑的 JavaScript 程式。它只是保存 JavaScript 原始碼的檔案。還需要瀏覽器、Node.js 或其他 JavaScript runtime 去讀取並執行。

Runtime:讓程式有地方跑

你之後會一直遇到 runtime 這個詞。先用一個夠用的版本理解:

程式碼 + 執行它所需要的環境 = 程式真正跑起來

JavaScript 可以在瀏覽器裡執行,也可以在 Node.js 這類 runtime 裡執行。Python 原始碼通常需要 Python runtime;Java 程式則會和 JVM 等執行環境打交道。

不同語言的實作細節差很多,但共同點是:你的文字必須交給某個能理解它的系統。

試一次:修改原始碼,再重新執行

回到 VS Code,把:

const message = "Hello, Norelyn Learn.";

改成你自己的內容,例如:

const message = "這是我第一次修改正在執行的程式。";

儲存後回到瀏覽器,重新整理頁面。

畫面應該跟著改變。

改原始碼 → 儲存 → 再次載入 → 再次執行 → 新輸出

注意:你只在 VS Code 打完字卻沒有儲存時,瀏覽器讀到的仍可能是硬碟上舊的版本。第二課學過的「畫面中的修改 ≠ 已儲存」現在直接影響程式執行結果。

為什麼要重新整理?

一般情況下,瀏覽器第一次開啟 run.html 時會讀取當時儲存的內容並執行。你之後在 VS Code 修改檔案,已經打開的頁面不會自動假設要全部重跑。

重新整理等於要求瀏覽器重新讀取文件,於是程式再次從頭執行。

未來你會遇到開發伺服器、Hot Reload、Hot Module Replacement 等工具,它們可以自動處理部分更新。但先理解最基本版本:

檔案改了 ≠ 已開啟的程式自動重跑

輸出不一定是畫面

程式的結果可以有很多形式。現在把 script 改成:

<script>
  const message = "Hello from console.";
  console.log(message);
</script>

儲存並重新整理。這次頁面上的文字不會被修改。

打開瀏覽器 Developer Tools 的 Console,你應該能看到:

Hello from console.

所以 output 不只代表「使用者看到的畫面」。它也可以是終端機文字、Console 訊息、檔案、網路回應、資料庫寫入,甚至控制硬體。

程式不是一直「讀整個檔案」這麼簡單

這一課用「runtime 讀取原始碼並執行」來建立基本模型,但真實世界還有不同處理方式。

有些語言常由 interpreter 或虛擬機器執行;有些程式會先經過 compiler 編譯成另一種形式,再由作業系統或其他 runtime 執行;現代 JavaScript 引擎也會做解析、最佳化與即時編譯。

現在不需要把 interpreter、compiler、JIT 全部背完。只要先避免一個錯誤觀念:副檔名不會自己讓電腦理解程式。

故意讓程式壞一次

把 script 改成下面這樣:

<script>
  const message = "Hello"
  document.querySelector("#not-exist").textContent = message;
</script>

儲存、重新整理後,你會發現頁面沒有如預期更新。打開 Console,通常能看到一段錯誤訊息。

這不是「瀏覽器壞了」,而是程式執行到某一步時遇到無法完成的操作。錯誤訊息就是 runtime 留給你的線索。

程式有錯 ≠ 程式完全沒有執行。有時它已經成功執行前幾行,只是在某一行失敗並停止後續流程。之後除錯時,要找的是「在哪一步開始和預期不同」。

再看一次完整流程

現在把前四課接起來:

檔案有路徑 → VS Code 修改原始碼 → 儲存到硬碟 → runtime 讀取 → 執行 → 產生輸出

這條鏈只要有任何一段搞錯,都可能出現「為什麼它沒反應」:

你可能改錯檔案、沒有儲存、開錯路徑、用錯 runtime、程式執行時報錯,或只是正在看舊的輸出。

所以除錯並不是一直重打程式碼,而是沿著這條鏈確認每一層。

可選:如果你的電腦已經有 Node.js

這部分不是完成課程的必要條件。如果你的電腦已經安裝 Node.js,可以再體驗一次「同一種語言、不同 runtime」。

建立 hello.js:

console.log("Hello from Node.js");

在 Terminal 確認自己位於專案根目錄,執行:

node hello.js

輸出會直接出現在 Terminal,而不是瀏覽器畫面。

hello.js → Node.js runtime → Terminal output

如果系統顯示找不到 node 指令,代表 Node.js 尚未安裝或沒有加入 PATH。這一課不用為了它額外處理環境設定,直接跳過即可。

小挑戰:讓使用者按按鈕改變輸出

把 run.html 整理成下面這個版本,但不要直接停在複製完成。先跑一次,再自己改內容:

<!doctype html>
<html lang="zh-Hant">
<body>
  <h1 id="output">等待操作</h1>
  <button id="run">執行</button>

  <script>
    const button = document.querySelector("#run");
    const output = document.querySelector("#output");

    button.addEventListener("click", () => {
      output.textContent = "程式剛剛回應了你的操作。";
    });
  </script>
</body>
</html>

完成後試著自己修改:

挑戰 1:把按鈕上的「執行」改成別的文字。

挑戰 2:把點擊後顯示的句子改掉。

挑戰 3:故意刪掉一個引號或括號,觀察 Console 出現什麼錯誤,再修回來。

你現在不需要理解每個 JavaScript 語法。Web Basics 會正式教。這裡的目標只有一個:親眼看到「使用者操作 → 程式執行 → 輸出改變」。

你剛剛真正學會了什麼?

寫程式不是把特殊文字放進檔案就完成。真正的流程至少包含:

Source Code → Runtime → Execution → Output

而你現在已經知道檔案與路徑在哪一層、編輯器在哪一層、Terminal 在哪一層,現在又補上執行環境這一層。

下一課開始學 Git。Git 不負責執行程式,它解決的是另一個問題:當你的專案開始一直修改,要怎麼知道自己改了什麼、留下哪些版本,以及需要時怎麼回頭。

完成條件:你能修改 run.html、儲存、重新執行並看到不同輸出,而且能用自己的話說明「原始碼不會自己跑,需要 runtime」。