JavaScript 與前端開發基礎:從 C# 開發者視角
本簡報專為熟悉 C# 等後端語言的開發者介紹 JavaScript 的主要特性,重點在於語言間的差異和前端開發中常用的 JavaScript 特性。
變數宣告與作用域:概述
三種宣告方式
JavaScript 中的變數宣告有三種方式:var、let 與 const。
作用域差異
每種宣告方式有不同的作用域規則,影響變數的可見範圍。
與 C# 的差異
JavaScript 的變數行為與 C# 有根本性的不同。
Var vs Let vs Const
提升 (Hoisting) 行為
JavaScript 特有機制
變數宣告會被提升到作用域頂部,但初始化不會。
console.log(x); // undefined var x = 10; // 相當於 var x; console.log(x); x = 10;
C# 的差異
C# 沒有提升機制,使用未宣告變數會導致編譯錯誤。
// C# 中 Console.WriteLine(x); // 編譯錯誤 int x = 10;
區塊作用域 vs 函式作用域
區塊作用域 (let/const)
變數僅在宣告的區塊內可見,類似 C#。
函式作用域 (var)
變數在整個函式內可見,無視區塊。
常見陷阱
var 在迴圈中的閉包問題。
全域變數與 Window 物件
var 的全域行為
使用 var 在最外層宣告的變數會成為 window 物件的屬性。
let/const 的全域行為
使用 let/const 宣告的變數不會附加到 window 物件上。
C# 的差異
C# 沒有類似的全域物件概念,變數總是有明確的作用域。
型別系統:概述
弱型別 vs 強型別
JavaScript 是弱型別語言,C# 是強型別語言。
動態 vs 靜態
JavaScript 變數可隨時改變型別;C# 變數型別固定。
型別安全
JavaScript 型別更簡單但也更容易出錯。
原始型別對比
數字
JavaScript 只有一種數字型別,C# 有多種數值型別。
字串
JavaScript 可使用單引號或雙引號,C# 只用雙引號。
布林值
兩種語言相似:true/false。
特殊型別
JavaScript 有 undefined 和 null,C# 只有 null。
動態型別轉換
JavaScript 自動轉換
console.log('5' == 5); // true console.log('' == 0); // true console.log(true == 1); // true
JavaScript 會自動進行型別轉換,這可能導致意外結果。
C# 明確轉換
// C# 中 // if ("5" == 5) // 編譯錯誤 // 需要明確轉換 if (int.Parse("5") == 5) // 正確
C# 需要明確的型別轉換,提供更高的型別安全性。
相等運算子:== vs ===
寬鬆相等 (==)
比較前進行型別轉換,可能導致意外結果。
嚴格相等 (===)
同時比較值和型別,不進行型別轉換。
C# 比較
C# 的 == 類似 JavaScript 的 ===,不會自動轉換型別。
函式與委派:概述
一級公民
JavaScript 函式是一級公民
多種宣告方式
函式宣告、函式表達式、箭頭函式
C# 對應
C# 使用委派或 Lambda 表達式
函式宣告模式
函式宣告
function add(a, b) { return a + b; }
會被提升,可在宣告前使用。
函式表達式
const multiply = function(a, b) { return a * b; };
不會被提升,必須在宣告後使用。
箭頭函式 (ES6)
const subtract = (a, b) => a - b;
簡潔語法,沒有自己的 this 綁定。
箭頭函式 vs 傳統函式
this 綁定差異
箭頭函式捕獲定義時的 this,傳統函式依呼叫方式決定。
無 arguments 物件
箭頭函式沒有自己的 arguments 物件。
簡潔語法
單一表達式可省略 return 和大括號。
不能作為建構子
箭頭函式不能用 new 關鍵字調用。
"this" 關鍵字行為
全域環境
指向全域物件 (window)
物件方法
指向呼叫該方法的物件
箭頭函式
捕獲定義時的 this 值
事件處理器
指向觸發事件的元素
物件與類別:概述
動態特性
JavaScript 物件比 C# 物件更為動態,可隨時添加或刪除屬性。
類別語法糖
ES6 引入的 class 語法實際上是原型繼承的語法糖。
原型繼承
JavaScript 使用原型鏈實現繼承,不同於 C# 的類繼承。
物件字面值建立
JavaScript 物件字面值
const person = { name: 'John', age: 30, greet() { return `Hello, I'm ${this.name}`; } };
無需類別定義,直接建立物件。
C# 物件初始化器
// C# 必須先定義類別 var person = new Person { Name = "John", Age = 30 };
C# 需要先定義類別,再實例化物件。
動態屬性管理
動態新增屬性
JavaScript 可在運行時動態新增物件屬性。
person.location = 'Taipei';
動態刪除屬性
可使用 delete 運算子移除屬性。
delete person.age;
C# 的差異
C# 物件結構固定,無法動態新增或刪除屬性。
ES6 類別語法
JavaScript 類別 (ES6)
class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { return `Hello, I'm ${this.name}`; } }
C# 類別
public class Person { public string Name { get; set; } public int Age { get; set; } public Person(string name, int age) { Name = name; Age = age; } public string Greet() { return $"Hello, I'm {Name}"; } }
類別繼承實現
1
定義基類
建立父類別
使用 extends
子類別繼承父類別
調用 super()
呼叫父類別建構子
擴展功能
新增或覆寫方法
原型鏈與繼承:概述
1
原型鏈基礎
JavaScript 使用原型鏈進行繼承,這與 C# 的類繼承有本質不同。
2
實例關係
每個物件都有一個指向其原型的內部連結。
3
方法查找
當訪問物件屬性時,會沿著原型鏈向上查找。