JavaScript note

宣告變數

var : 對於較舊的代碼或更廣泛的範圍

  • var age = 25;

let : 對於可能發生變化的變數

  • let city = “New York”;

const : 對於保持不變的值

  • const country = “USA”

如何宣告變數?

let name = “Alice”; // String

let age = 25; // Number

let isStudent = true; // Boolean

let scores = [95, 85, 76]; // Array

let person = {name: “Alice”, age: 25}; // Object

如何使用運算符?

算術運算子:使用 +、-、*、/ 和 % 進行數學運算。

let sum = 10 + 5; // 加法

let product = 10 * 2; // 乘法

賦值運算子:使用 =、+=、-= 等賦值。

let total = 100; 

total += 20; // 總數現在是 120

比較運算子:使用 ==、===、!= 等比較值

let a = 10;  設 a = 10;

let b = ’10’;  令 b = ’10’;

console.log(a == b); // true(鬆散比較)

console.log(a === b); // false (嚴格比較,還包含類型比較)

邏輯運算子:使用 && 、 || 和 ! 組合條件 。

let x = true;

let y = false;  

console.log(x && y); // false

console.log(x || y); // true

如何輸出內容?

Console.log(‘Hellow World’)  

他是 Web 開發的核心概念,它將網頁結構表示為分層節點樹。使用 JavaScript,開發者可以與此模型交互,動態更新內容、佈局和樣式,從而打造互動式、響應式的使用者體驗。

選擇和存取元素

  • document.getElementById()
  • document.getElementsByClassName()
  • document.querySelector()

操作內容、屬性和樣式

  • element.textContent : 修改元素內的文字
  • element.innerHTML : 修改元素內的 HTML
  • element.setAttribute() : 動態更新映像的 src 等屬性 ,從而允許根據使用者操作快速變更。
  • element.style.property : 可以直接修改內聯樣式
    • header.style.color = ‘blue’ ,將header的顏色調整成藍色

新增和刪除元素

  • document.createElement() : 新增元素
  • element.parentNode.removeChild(element) : 刪除元素

處理互動事件

  • addEventListener() : 事件監聽器可以偵測使用者的動作
  • 範例:當點擊按鈕的時候quoteDisplay的文字會隨機變化
    • const quoteDisplay = document.getElementById(‘quoteDisplay’);
    • const quotes = [
    • “隨機的第一句.”,
    • “隨機的第二句.”,
    • “隨機的第三句.” ];
    • button.addEventListener(‘click’, function() {
    • const randomIndex = Math.floor(Math.random() * quotes.length);
    • quoteDisplay.textContent = quotes[randomIndex];
    • });

函式類型

  • 函式宣告:使用關鍵字定義命名函式

function greet() { 

  console.log(“Hello, world!”);

}

greet();  // Output: Hello, world!

  • 函式表達式:在表達式中定義一個函式

const greet = function() {

  console.log(“Hello, world!”);

};

greet();  // Output: Hello, world!

  • 箭頭函式:為函式表達式提供較短的語法,非常適合簡單任務。

const greet = () => console.log(“Hello, world!”);

Scope in JavaScript

全域宣告就是可以在全部地方使用,在函式內部宣告的只能在內部使用。

非同步程式設計 Async/Await 

假設有一個按鈕 (id = “fetch-data”):

  • fetch : 當呼叫時會立即返回一個承諾,來表示正在執行請求
  • await : 確保請求被執行完後才會繼續向下執行。
  • map : 會遍歷陣列中的物件,將指定的物件放入新建的陣列中
  • join : 能夠將字串的元素連接起來

async function fetchDataAsync() {

  try {

    const response = await fetch(‘https://jsonplaceholder.typicode.com/users’); // API call

    const data = await response.json(); // Parse the response

    if (!response.ok) {

      throw new Error(`Status: ${response.status}`); // Handle non-OK responses

    }

    const container = document.getElementById(‘data-container’); // Select the container

    container.innerHTML = data

      .map(user => `<p>${user.name} – ${user.email}</p>`) // Display user data

      .join(”);

  } catch (error) {

    console.error(‘Error fetching data:’, error); // Log errors

  }

}

// Add event listener to button

document.getElementById(‘fetch-data’).addEventListener(‘click’, fetchDataAsync); // Fetch data on click

Module Pattern  模組模式

就像一個藏寶箱,他會把相關的程式碼(變數、函式)都放在一個獨立的箱子裡,裡面的東西是私密的,所以外面的人無法看到也拿不到,只有寶箱的主人才能夠拿出來給其他人看到跟使用。

  • 封裝私有變數和函式,避免全域命名空間衝突,還能夠保護函式的核心邏輯。
  • 建立自包含、可重複使用的程式碼區塊,保持程式碼庫井然有序。
  • 範例:使用立即呼叫函式表達式 (IIFE) 來限制對私有變數的存取並僅公開必要的函式。

// 這是一個立即執行函式運算式 (IIFE)。

// 它會立刻執行,並建立一個獨立的、私密的作用域(Scope),就像一個密閉的「藏寶箱」。

const myModule = (function() {

   // 這是私有變數,外面無法直接存取(寶箱裡的寶物)

   let privateVariable = ‘我是私密的’;

   // 這是私有方法(寶箱裡的寶物)

   function privateMethod() {

     console.log(‘我是一個私密方法’);

   }

   // 返回一個包含公開屬性和方法的物件(寶箱鑰匙)

   return {

     publicMethod: function() {

       console.log(privateVariable); // 公開方法可以存取私有變數

     },

     publicVariable: ‘我是公開的’

   };

})();

myModule.publicMethod(); // 執行公開方法

console.log(myModule.publicVariable); // 存取公開變數

// console.log(myModule.privateVariable); // 錯誤,無法存取私有變數

就像訂閱一樣,當某個東西的狀態有改變,只要有訂閱的人都會自動收到通知,發布者不知道誰訂閱,訂閱者也不知道其他訂閱者的存在。

  • 透過通知訂閱的「觀察者」狀態變化來管理物件通信,非常適合事件驅動系統。
  • 幫助協調應用程式多個部分的更新。
  • 範例:「主題」類別維護觀察者列表,當事件發生時通知每個變化。

// 發布者(Subject):這個類別負責管理觀察者,並在狀態改變時通知他們。

class Subject {

  constructor() {

    this.observers = [];  // 建構子:在建立發布者時,初始化一個空的陣列來存放所有訂閱者。

  }

// 當一個觀察者呼叫這個方法時,它會將自己加入到發布者的訂閱清單中。

  subscribe(observer) {

    this.observers.push(observer);

  }

 // 當發布者的狀態改變時,它會呼叫這個方法,遍歷所有訂閱者。  

 // 並對每個訂閱者呼叫他們的 update 方法,將新資料傳遞給他們。

  notify(data) {

    this.observers.forEach(observer => observer.update(data));

  }

}

// 觀察者(Observer):這個類別負責接收來自發布者的通知。

class Observer {    

// update 方法:當發布者通知時,會自動呼叫這個方法。 

// 它可以接收並處理發布者傳來的資料。

  update(data) {

    console.log(‘收到新資料:’, data);

  }

}

// 建立一個發布者實例,就像一個 YouTube 頻道。

const publisher = new Subject();

// 建立一個發布者實例,就像一個 YouTube 頻道。

const subscriber1 = new Observer();

const subscriber2 = new Observer();

// 讓這兩個訂閱者都去「訂閱」這個頻道。

publisher.subscribe(subscriber1);

publisher.subscribe(subscriber2);

// 頻道的狀態改變了(發布了一部新影片),發布者開始通知所有訂閱者。 

// 每個訂閱者的 update 方法都會被呼叫,並收到「新的 YouTube 影片發布了!」這則訊息。

publisher.notify(‘新的 YouTube 影片發布了!’);

確保一個類別只有一個實例,從而提供整個系統的單一存取點。

對於需要集中控制的資源很有用,例如單一管理器或控制器。

範例:在類別中使用實例檢查來防止建立多個實例,並維護單一參考。

// 這個類別只能被實例化一次

class Singleton {

  // 建構子:在建立新物件時,會自動執行這個方法。

  constructor() {

    // 檢查類別本身(Singleton)是否已經有一個名為 ‘instance’ 的靜態屬性。

    // 如果 ‘instance’ 不存在(也就是第一次建立),就會執行 if 區塊。

    if (!Singleton.instance) {

      // 第一次建立時,將新建立的實例(this)賦值給 ‘instance’。

      // 這樣,這個實例就被保存下來,下次就不會再建立了

      Singleton.instance = this;

    }

    // 無論是第一次建立,還是之後的每一次建立,都會返回這個唯一的實例。

    return Singleton.instance;

  }

  // 這是單例實例的一個公開方法,可以用來執行某些操作。

  logMessage(message) {

    console.log(‘日誌記錄:’, message);

  }

}

// 嘗試建立第一個實例。

// 程式會進入建構子的 if 區塊,建立唯一的實例並保存起來。

const instance1 = new Singleton();

// 嘗試建立第二個實例。

// 這次,建構子會發現 ‘Singleton.instance’ 已經存在,

// 所以它會直接返回之前建立的那個實例,而不是建立一個新的。

const instance2 = new Singleton();

// 使用嚴格相等(===)來檢查這兩個變數是否引用同一個物件。

// 結果為 true,證明 instance1 和 instance2 其實是同一個實例。

console.log(instance1 === instance2);

// 在 instance1 和 instance2 上呼叫 logMessage 方法,

// 但它們實際上都是在操作同一個物件。

instance1.logMessage(‘這是第一個訊息’);

instance2.logMessage(‘這是第二個訊息’);

JSON.parse() : 將 JSON 字串轉換為 JavaScript 物件,使資料可以在 JavaScript 應用程式中使用。

  • let jsonObject = JSON.parse(‘{“name”: “Alice”, “age”: 25}’);
  • console.log(jsonObject.name); // Outputs: Alice

JSON.stringify(): 將 JavaScript 物件轉換為 JSON 字串,這對於以標準格式傳輸或儲存資料很有用。

  • let jsonString = JSON.stringify({ name: “Bob”, age: 30 });
  • console.log(jsonString); // Outputs: {“name”:”Bob”,”age”:30}

JSON 的常見用途

  • 從 API 取得資料:API 經常使用 JSON 傳回可解析為 JavaScript 以供應用程式使用的資料。
  • 本機資料儲存:JSON 可以將使用者設定或資料儲存在瀏覽器本機,從而增強可存取性和效能。
  • 設定檔:JSON 的清晰結構使其成為設定檔的理想選擇,可儲存易於存取和修改的設定。

JSON 結構和語法

  • 以大括號 {} 表示的鍵值對的集合 ,值範圍包括字串、數字、布林值、空值、陣列或其他物件。
  • 用方括號 [] 表示數組,包含任何類型的數據,包括其他數組和物件。
  • 用冒號 : 為鍵賦值,
  • 用逗號 , 分隔元素。

發佈留言