JavaScript - 引用型別



JavaScript 引用型別

JavaScript 中有兩種資料型別:原始型別和引用型別。

原始資料型別是不可變的,這意味著它們不能被更改。JavaScript 中的原始資料型別包括:Number、String、Boolean、Undefined、Null、Symbol。

引用資料型別是可變的,這意味著它們可以被更改。JavaScript 中的引用資料型別包括:Object、Array、Function。

當您將原始資料型別賦值給變數時,變數會獲得該值的副本。當您將引用資料型別賦值給變數時,變數會獲得對該值的引用。這意味著,如果您更改了引用資料型別的值,則更改將反映在所有引用該值的變數中。

例如,以下程式碼建立了兩個變數 x 和 y,併為它們賦值 10

let x = 10;
let y = 10;

變數 x 和 y 都擁有值 10 的副本。如果您更改了 x 的值,y 的值不會改變。

x = 20;
console.log(x); // 20
console.log(y); // 10

以下程式碼建立了兩個變數 x 和 y,併為它們賦值一個數組

const x = [1, 2, 3];
const y = x;

變數 x 和 y 都引用了同一個陣列。如果您更改了 x 引用的陣列的值,則更改將反映在 y 引用的陣列中。

x[0] = 4;
console.log(x); // [4, 2, 3]
console.log(y); // [4, 2, 3]

瞭解 JavaScript 中原始型別和引用型別之間的區別非常重要,這樣您才能編寫出高效且可預測的程式碼。

物件和函式是 JavaScript 中兩種主要的引用型別,解釋如下。

物件

物件是鍵值對的無序集合,其中鍵是字串或符號,值可以是任何資料型別,包括其他物件。

const person = {
  firstName: "John",
  lastName: "Doe",
  age: 30
};

函式

函式在 JavaScript 中也是引用型別。函式是可呼叫的特殊型別的物件,用於執行任務。

function greet(name) {
  alert("Hello, " + name + "!");
}

示例

示例 1:物件可變性

在此示例中,我們演示了物件的可變性,首先建立一個物件,然後透過該引用進行修改,這反過來會影響原始物件。person 物件透過 anotherPerson 的引用進行修改,準確地說是年齡從 25 更改為 30。從輸出中可以看到,原始物件在修改後發生了變化,因此物件被認為是發生了變異。

<!DOCTYPE html>
<html>
<body>
   <h2>JavaScript Reference Types Example: Object Mutability</h2>
   <script>
      // Create an object
      const person = {
         name: "John",
         age: 25
      };

      // Create a reference to the object
      let anotherPerson = person;

      // Display the original object
      document.write("<p>Original Object: " + JSON.stringify(person) + "</p>");

      // Modify the object through the reference
      anotherPerson.age = 30;

      // Display the modified object
      document.write("<p>Modified Object: " + JSON.stringify(person) + "</p>");

      // Both references point to the same object, so changes are reflected in both
      document.write("<p>Original Object after modification through reference: " + JSON.stringify(person) + "</p>");
   </script>
</body>
</html>

示例 2:陣列修改

此處演示了陣列,陣列可以在 JavaScript 中的單個變數記憶體儲不同資料型別的多個值。它們表現出可變性,這意味著當對陣列進行引用時,對引用的更改也會反映在原始陣列中。這裡我們建立了一個顏色的陣列並透過 moreColors 的引用對其進行修改,主要是透過推送元素“yellow”。

<!DOCTYPE html>
<html>
<body>
   <h2>JavaScript Reference Types Example: Array Modification</h2>
   <script>
      // Create an array
      const colors = ["red", "green", "blue"];

      // Create a reference to the array 
      let moreColors = colors;

      // Display the original array
      document.write("<p>Original Array: " + JSON.stringify(colors) + "</p>");

      // Modify the array through the reference
      moreColors.push("yellow");

      // Display the modified array
      document.write("<p>Modified Array: " + JSON.stringify(colors) + "</p>");

      // Both references point to the same array, so changes are reflected in both
      document.write("<p>Original Array after modification through reference: " + JSON.stringify(colors) + "</p>");
   </script>
</body>
</html>

示例 3:函式引用型別

在此示例中,我們建立了一個函式 greet,其引用最初被分配給 greetingFunction。在使用它說 Hello 後,我們將引用修改為指向一個不同的函式,該函式用 Hola 打招呼。這演示了 JavaScript 中函式引用的靈活性。

<!DOCTYPE html>
<html>
<body>
   <h2>JavaScript Reference Types Example: Function Invocation</h2>
   <script>
      // Create a function
      function greet(name) {
         return "Hello, " + name + "!";
      }

      // Create a reference to the function
      let greetingFunction = greet;

      document.write("<p>Original Function Result: " + greetingFunction("John") + "</p>");
    
      greetingFunction = function(name) {
         return "Hola, " + name + "!";
      };

      document.write("<p>Modified Function Result: " + greetingFunction("Maria") + "</p>");
   </script>
</body>
</html>

示例 4:自定義類

此示例演示了 JavaScript 中的自定義類,從引用型別的角度來看,這是另一個關鍵方面。該類包含屬性和函式/方法。這裡我們建立一個名為 Book 的類,它具有建構函式和方法。建立了該 book 類的 4 個例項(book1、book2、book3、book4),併為其提供了相應的資料,例如標題、作者和流派。

<!DOCTYPE html>
<html>
<body>
   <h2>JavaScript Reference Types Example: Custom class</h2>
   <script>
      // Define a custom class for Book
      class Book {
         constructor(title, author, genre) {
            this.title = title;
            this.author = author;
            this.genre = genre;
         }

         // Method to get book details
         getDetails() {
            return `Title: ${this.title}<br>Author: ${this.author}<br>Genre: ${this.genre}`;
         }
      }

      // Create instances of the Book class
      const book1 = new Book("The Great Gatsby", "F. Scott Fitzgerald", "Fiction");
      const book2 = new Book("To Kill a Mockingbird", "Harper Lee", "Classics");
      const book3 = new Book("Harry Potter and the Sorcerer's Stone", "J.K. Rowling", "Fantasy");
      const book4 = new Book("1984", "George Orwell", "Dystopian Fiction");

      document.write("<h3>Book 1 Details:</h3>");
      document.write("<p>" + book1.getDetails() + "</p>");

      document.write("<h3>Book 2 Details:</h3>");
      document.write("<p>" + book2.getDetails() + "</p>");

      document.write("<h3>Book 3 Details:</h3>");
      document.write("<p>" + book3.getDetails() + "</p>");

      document.write("<h3>Book 4 Details:</h3>");
      document.write("<p>" + book4.getDetails() + "</p>");
   </script>
</body>
</html>

示例 5:不可變物件

本示例重點關注物件的不可變性,這在建立物件時使用 `Object.freeze()` 方法實現。不可變性基本上意味著物件在建立後不會改變,或者簡單地說,一旦定義了物件,就不能修改其屬性。這裡我們建立了一個名為“person”的物件,其屬性為“name”和“age”,然後嘗試將“age”更改為 35。但是,由於物件的凍結狀態,此修改被阻止並丟擲錯誤。不可變性是一個重要的方面,因為它有助於維護資料完整性,從而防止意外更改並增強程式碼執行的可預測性。

<!DOCTYPE html>
<html>
<body>
   <h2>Immutable Object with Error Handling</h2>
   <script>
      // Enable strict mode
      'use strict';

      // Create an immutable object
      const person = Object.freeze({
         name: "Alice",
         age: 30
      });

      document.write("<p><strong>Before Modification:</strong></p>");
      document.write("<p>Name: " + person.name + "</p>");
      document.write("<p>Age: " + person.age + "</p>");

      try {
         // Attempting to modify the object will result in an error
         person.age = 35;
      } catch (error) {
         document.write(error);
      }

      document.write("<p><strong>After Modification Attempt:</strong></p>");
      document.write("<p>Name: " + person.name + "</p>");
      document.write("<p>Age: " + person.age + "</p>");
   </script>
</body>
</html>
廣告