這一課完成後:你會分清楚原始碼、執行環境與輸出,知道為什麼同一個檔案需要某個程式來讀它,也能第一次自己修改程式並觀察結果。
先做:建立第一個真的會執行的檔案
打開你的 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 就自己啟動。
真正發生的是:
瀏覽器在這裡不只是「顯示網頁的 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 留給你的線索。
程式有錯 ≠ 程式完全沒有執行。有時它已經成功執行前幾行,只是在某一行失敗並停止後續流程。之後除錯時,要找的是「在哪一步開始和預期不同」。
再看一次完整流程
現在把前四課接起來:
這條鏈只要有任何一段搞錯,都可能出現「為什麼它沒反應」:
你可能改錯檔案、沒有儲存、開錯路徑、用錯 runtime、程式執行時報錯,或只是正在看舊的輸出。
所以除錯並不是一直重打程式碼,而是沿著這條鏈確認每一層。
可選:如果你的電腦已經有 Node.js
這部分不是完成課程的必要條件。如果你的電腦已經安裝 Node.js,可以再體驗一次「同一種語言、不同 runtime」。
建立 hello.js:
console.log("Hello from Node.js");
在 Terminal 確認自己位於專案根目錄,執行:
node hello.js
輸出會直接出現在 Terminal,而不是瀏覽器畫面。
如果系統顯示找不到 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 會正式教。這裡的目標只有一個:親眼看到「使用者操作 → 程式執行 → 輸出改變」。
你剛剛真正學會了什麼?
寫程式不是把特殊文字放進檔案就完成。真正的流程至少包含:
而你現在已經知道檔案與路徑在哪一層、編輯器在哪一層、Terminal 在哪一層,現在又補上執行環境這一層。
下一課開始學 Git。Git 不負責執行程式,它解決的是另一個問題:當你的專案開始一直修改,要怎麼知道自己改了什麼、留下哪些版本,以及需要時怎麼回頭。
完成條件:你能修改 run.html、儲存、重新執行並看到不同輸出,而且能用自己的話說明「原始碼不會自己跑,需要 runtime」。