JavaScript學習

Dreaife發表於2024-12-09

關於js

JavaScript 是一種動態的、弱型別的解釋型語言,最初設計用於瀏覽器端的互動。

特點

  • 輕量級:語法簡單,入門門檻低。
  • 跨平臺:支援在瀏覽器、Node.js 等多種環境中執行。
  • 解釋型:無需編譯,直接在執行時執行。
  • 事件驅動:非常適合處理非同步任務,如使用者互動、網路請求等。

核心概念

  • 變數與資料型別

    • JavaScript 是動態型別語言,可以儲存任何型別的資料。

    • 變數宣告使用 var(老式方式),let(推薦),或 const(推薦)。

      let name = "JavaScript";  // 字串
      const version = 2024;    // 數字
      var isCool = true;       // 布林值
      
  • 基本資料型別

    • 原始型別StringNumberBooleanundefinednullSymbolBigInt

    • 複雜型別Object(包括陣列、函式等)

      let array = [1, 2, 3]; // 陣列
      let obj = { key: "value" }; // 物件
      
  • 控制流

    • 條件語句:if-elseswitch

    • 迴圈:forwhileforEach

      for (let i = 0; i < 3; i++) {
          console.log(i);
      }
      
  • 函式

    • 可以定義普通函式或箭頭函式。

      function greet(name) {
          return `Hello, ${name}!`;
      }
      
      const greetArrow = (name) => `Hello, ${name}!`;
      
  • 事件驅動與非同步

    • 使用 setTimeoutsetInterval 定時執行。

    • 使用 Promiseasync/await 處理非同步操作。

      const fetchData = async () => {
          let response = await fetch("https://api.example.com/data");
          let data = await response.json();
          console.log(data);
      };
      

JS 的執行環境

  1. 瀏覽器

    • JavaScript 最初是為瀏覽器設計,用於動態操作 DOM(網頁內容)。

    • 示例:點選按鈕時彈出提示框。

      javascript
      複製程式碼
      document.querySelector("button").addEventListener("click", () => {
          alert("Button clicked!");
      });
      
  2. 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 宣告的變數只在函式內可用。
    • 塊作用域:使用 letconst 宣告的變數只在程式碼塊 {} 內可用。
  • 變數提升
    • var 會被提升,但值未賦予時是 undefined
    • letconst 不會被提升

1.2 資料型別

  • 基本型別StringNumberBooleanundefinednullSymbolBigInt
  • 複雜型別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-elseswitch、三元運算子。

示例

const age = 18;
const message = age >= 18 ? "Adult" : "Minor";
console.log(message);

邏輯運算子

if 條件中經常使用邏輯運算子,結合多個條件判斷。

  • 邏輯與(&&):所有條件為真時,返回真。
  • 邏輯或(||):只要有一個條件為真,返回真。
  • 邏輯非(!):將條件取反。

真假值(Truthy 和 Falsy)

JavaScript 中一些值在布林上下文中會被認為是真或假。

  • Falsy(假值)false0""(空字串)、nullundefinedNaN
  • Truthy(真值):除了 Falsy 以外的所有值。

1.4 迴圈

  • forwhiledo-whilefor...infor...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 作用域與閉包

  • 全域性作用域、函式作用域、塊作用域。
    • 全域性作用域:在函式之外宣告的變數,可以被整個程式訪問。
    • 函式作用域:在函式內部宣告的變數,只能在函式內部訪問。
    • 塊作用域letconst 宣告的變數,只在塊 {} 內可訪問。
  • 閉包:函式捕獲其定義時的作用域變數,通常用於建立私有變數或函式。

示例

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...inObject.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 指向的是全域性作用域(在瀏覽器中,thiswindow;在 Node.js 中是 global),而不是 person

因此,this.prop 是未定義的,因為全域性作用域中沒有 prop 屬性。

3.2 陣列操作

  • 常用方法:pushpopmapfilterreduce
    • 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 模組化

  • 匯出模組:exportexport default
  • 匯入模組:importimport * 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 是一個物件,表示一個非同步操作的最終完成或失敗。它有以下三種狀態:

    1. Pending(進行中):初始狀態,未完成或失敗。
    2. Fulfilled(已完成):操作成功,返回結果。
    3. 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

  1. async 用於宣告一個函式,使其返回一個 Promise
  2. await 用於暫停程式碼執行,等待 Promise 解決(resolve)後再繼續。

示例

async function fetchData() {
    const response = await fetch("<https://api.myip.com>");
    const data = await response.json();
    console.log(data);
}
fetchData();

相關文章