關於js
JavaScript 是一種動態的、弱型別的解釋型語言,最初設計用於瀏覽器端的互動。
特點
- 輕量級:語法簡單,入門門檻低。
- 跨平臺:支援在瀏覽器、Node.js 等多種環境中執行。
- 解釋型:無需編譯,直接在執行時執行。
- 事件驅動:非常適合處理非同步任務,如使用者互動、網路請求等。
核心概念
-
變數與資料型別
-
JavaScript 是動態型別語言,可以儲存任何型別的資料。
-
變數宣告使用
var
(老式方式),let
(推薦),或const
(推薦)。let name = "JavaScript"; // 字串 const version = 2024; // 數字 var isCool = true; // 布林值
-
-
基本資料型別
-
原始型別:
String
、Number
、Boolean
、undefined
、null
、Symbol
、BigInt
-
複雜型別:
Object
(包括陣列、函式等)let array = [1, 2, 3]; // 陣列 let obj = { key: "value" }; // 物件
-
-
控制流
-
條件語句:
if-else
、switch
-
迴圈:
for
、while
、forEach
for (let i = 0; i < 3; i++) { console.log(i); }
-
-
函式
-
可以定義普通函式或箭頭函式。
function greet(name) { return `Hello, ${name}!`; } const greetArrow = (name) => `Hello, ${name}!`;
-
-
事件驅動與非同步
-
使用
setTimeout
和setInterval
定時執行。 -
使用
Promise
或async/await
處理非同步操作。const fetchData = async () => { let response = await fetch("https://api.example.com/data"); let data = await response.json(); console.log(data); };
-
JS 的執行環境
-
瀏覽器
-
JavaScript 最初是為瀏覽器設計,用於動態操作 DOM(網頁內容)。
-
示例:點選按鈕時彈出提示框。
javascript 複製程式碼 document.querySelector("button").addEventListener("click", () => { alert("Button clicked!"); });
-
-
Node.js
-
Node.js 是 JavaScript 的服務端執行環境。
-
示例:建立一個簡單的 HTTP 伺服器。
javascript 複製程式碼 const http = require("http"); const server = http.createServer((req, res) => { res.end("Hello, Node.js!"); }); server.listen(3000, () => console.log("Server running at http://localhost:3000"));
-
JavaScript基礎
第一章:JavaScript 基礎
1.1 變數與常量
- 變數宣告方式:
var
(不推薦):函式作用域。let
(推薦):塊作用域,允許重新賦值。const
(推薦):塊作用域,不允許重新賦值。
示例:
let age = 25;
const name = "Alice";
console.log(`${name} is ${age} years old.`);
- 變數的作用域
- 全域性作用域:宣告在函式之外,整個程式都可以訪問。
- 函式作用域:使用
var
宣告的變數只在函式內可用。 - 塊作用域:使用
let
或const
宣告的變數只在程式碼塊{}
內可用。
- 變數提升
var
會被提升,但值未賦予時是undefined
。let
和const
不會被提升。
1.2 資料型別
- 基本型別:
String
、Number
、Boolean
、undefined
、null
、Symbol
、BigInt
- 複雜型別:
Object
(包括陣列、函式等)
示例:
let age = 25; // 整數
let price = 19.99; // 浮點數
let result = "abc" / 2; // NaN
let infinite = 1 / 0; // Infinity
let name = "John";
let greeting = `Hello, ${name}!`; // 模板字串
console.log(greeting); // Hello, John!
let isOnline = true;
let hasPermission = false;
let x;
console.log(x); // undefined
let y = null;
console.log(y); // null
let bigNum = 123456789012345678901234567890n;
console.log(bigNum); // 123456789012345678901234567890n
let person = {
name: "Alice",
age: 30,
};
console.log(person.name); // Alice
let numbers = [1, 2, 3, 4];
console.log(numbers[0]); // 1
console.log(typeof 123); // "number"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (這是一個歷史遺留問題)
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
// 型別轉換
let str = String(123); // 轉為字串
let num = Number("123"); // 轉為數字
let bool = Boolean(1); // 轉為布林值
console.log("5" + 2); // "52" (字串拼接)
console.log("5" - 2); // 3 (字串轉數字後計算)
console.log(true + 1); // 2 (布林值轉為數字)
1.3 條件語句
if-else
、switch
、三元運算子。
示例:
const age = 18;
const message = age >= 18 ? "Adult" : "Minor";
console.log(message);
邏輯運算子
if
條件中經常使用邏輯運算子,結合多個條件判斷。
- 邏輯與(&&):所有條件為真時,返回真。
- 邏輯或(||):只要有一個條件為真,返回真。
- 邏輯非(!):將條件取反。
真假值(Truthy 和 Falsy)
JavaScript 中一些值在布林上下文中會被認為是真或假。
- Falsy(假值):
false
、0
、""
(空字串)、null
、undefined
、NaN
。 - Truthy(真值):除了 Falsy 以外的所有值。
1.4 迴圈
for
、while
、do-while
、for...in
、for...of
示例:
for (initialization; condition; increment) {
// 迴圈體:在條件為 true 時重複執行的程式碼
}
while (condition) {
// 迴圈體
}
do {
// 迴圈體
} while (condition);
for (const element of iterable) {
// 迴圈體:每次迭代都會賦值一個元素給 element
}
for (const key in object) {
// 迴圈體:每次迭代都會賦值一個屬性名給 key
}
控制迴圈:break 和 continue
break
:退出整個迴圈。continue
:跳過本次迴圈,直接進入下一次。
第二章:函式與作用域
2.1 函式基礎
- 普通函式、函式表示式、箭頭函式。
- 預設引數、不定引數。
示例:
const greet = (name = "Guest") => `Hello, ${name}!`;
console.log(greet("Alice"));
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // 輸出: Hello, Guest!
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 輸出: 10
2.2 作用域與閉包
- 全域性作用域、函式作用域、塊作用域。
- 全域性作用域:在函式之外宣告的變數,可以被整個程式訪問。
- 函式作用域:在函式內部宣告的變數,只能在函式內部訪問。
- 塊作用域:
let
和const
宣告的變數,只在塊{}
內可訪問。
- 閉包:函式捕獲其定義時的作用域變數,通常用於建立私有變數或函式。
示例:
function outerFunction() {
let counter = 0;
return function () {
return ++counter;
};
}
const increment = outerFunction();
console.log(increment()); // 1
console.log(increment()); // 2
function createMultiplier(multiplier) {
return function (value) {
return value * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 輸出: 10
console.log(triple(5)); // 輸出: 15
第三章:物件與陣列
3.1 物件操作
- 建立物件、訪問屬性、修改屬性、刪除屬性。
- 建立:{},new Object(),class
- 訪問:\({class}.prop,\){class}[prop]
- 修改/刪除
- 遍歷物件:
for...in
、Object.keys()
、Object.entries()
。
示例:
const person = { name: "Alice", age: 25 };
console.log(person.name); // Alice
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
**Object.keys(person).forEach((key) => {
console.log(`${key}: ${person[key]}`);
});**
Object.entries(person).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
tips:如果在class中使用()的話:
使用this的時候會呼叫不了clas內部的屬性,這是因為箭頭函式 () => {}
的 this
行為與普通函式不同。箭頭函式不會建立自己的 this
,而是繼承自它定義時的外部上下文。
- 箭頭函式的
this
繼承自frunction
定義時的作用域。 frunction
定義在class
物件的上下文中,但箭頭函式的this
指向的是全域性作用域(在瀏覽器中,this
是window
;在 Node.js 中是global
),而不是person
。
因此,this.prop
是未定義的,因為全域性作用域中沒有 prop
屬性。
3.2 陣列操作
- 常用方法:
push
、pop
、map
、filter
、reduce
。push()
:新增到陣列末尾。pop()
:從陣列末尾移除。unshift()
:新增到陣列開頭。shift()
:從陣列開頭移除。indexOf()
:找到第一個匹配的索引。includes()
:檢查是否包含某個元素。forEach()
:對每個元素執行操作。map()
:返回一個新陣列,包含每個元素的處理結果。filter()
:篩選滿足條件的元素。reduce()
:對陣列進行累積計算。
- 解構賦值與展開運算子。
示例:
const numbers = [1, 2, 3];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 6
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 輸出: 1 2 3
第四章:高階語法與模組化
4.1 解構賦值與展開運算子
- 解構:快速提取陣列或物件中的值。
- 展開運算子:快速複製或合併物件/陣列。
示例:
const [x, , ...z] = [1, 2, 3, 4, 5];
console.log(x, z); // 輸出: 1 [3,4,5]
const { name, age } = { name: "Alice", age: 25 };
console.log(name, age); // Alice 25
4.2 模板字串
- 使用反引號(```)動態生成字串。
示例:
const name = "Alice";
console.log(`Hello, ${name}!`);
4.3 模組化
- 匯出模組:
export
和export default
。 - 匯入模組:
import
、import * as
。
示例:
// module.js
export function greet(name) {
return `Hello, ${name}!`;
}
// main.js
import { greet } from './module.js';
console.log(greet("Alice"));
tips:
export default預設匯出每個模組只有一個,匯入時不需要{}。
當使用export * as test from “test.js”
時可以直接用test.default
第五章:非同步程式設計
5.1 回撥函式
- 非同步任務完成時呼叫回撥函式。
示例:
setTimeout(() => console.log("Task complete"), 1000);
- 回撥地獄
當多個非同步任務需要按順序執行時,巢狀的回撥函式會導致程式碼難以維護,這種現象被稱為“回撥地獄”。
setTimeout(() => {
console.log("Task 1 complete");
setTimeout(() => {
console.log("Task 2 complete");
setTimeout(() => {
console.log("Task 3 complete");
}, 1000);
}, 1000);
}, 1000);
為了解決回撥地獄的問題,可以使用 Promise。
5.2 Promise
-
使用
Promise
鏈式處理非同步任務。Promise
是一個物件,表示一個非同步操作的最終完成或失敗。它有以下三種狀態:- Pending(進行中):初始狀態,未完成或失敗。
- Fulfilled(已完成):操作成功,返回結果。
- Rejected(已失敗):操作失敗,返回錯誤。
示例:
const promise = new Promise((resolve, reject) => {
// 非同步操作
if (success) {
resolve(value); // 成功時呼叫 resolve
} else {
reject(error); // 失敗時呼叫 reject
}
});
fetch("<https://api.myip.com>")
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error(error));
5.3 async/await
async
用於宣告一個函式,使其返回一個Promise
。await
用於暫停程式碼執行,等待Promise
解決(resolve)後再繼續。
示例:
async function fetchData() {
const response = await fetch("<https://api.myip.com>");
const data = await response.json();
console.log(data);
}
fetchData();