Javascript 简明教程

JavaScript - Reference Type

JavaScript Reference Type

JavaScript 中有两种类型的数据类型:原始类型和引用类型。

原始数据类型是不可变的,这意味着不可更改原始数据类型。JavaScript 中的原始数据类型有:数字、字符串、布尔值、未定义、空、符号。

引用数据类型是可变的,这意味着可以更改引用数据类型。JavaScript 中的引用数据类型有:对象、数组、函数。

当你向变量分配原始数据类型时,该变量将获得该值的副本。当你向变量分配引用数据类型时,该变量将获得对该值的引用。这意味着,如果你更改引用数据类型的值,该更改将反映在所有引用该值的所有变量中。

例如,以下代码创建了两个变量 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 中的两个主要引用类型,解释如下。

Object

对象是无序键值对集合,其中键是字符串或符号,值可以是任何数据类型,包括其他对象。

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

Function

函数在 JavaScript 中也是引用类型。函数是可以调用(称为)以执行任务的特殊类型的对象。

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

Examples

Example 1: Object Mutability

在此示例中,我们演示了对象可变性,首先创建对象,然后通过该引用进行修改,进而影响原始对象。person 对象通过另一个人的引用进行修改,确切地说是将年龄从 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>

Example 2: Array Modification

这里演示了数组,它可以在单个变量中存储 JavaScript 中不同数据类型的多个值。它们表现出可变性,这意味着当引用数组时,对引用的更改也会反映在原始数组中。在这里,我们创建一个颜色数组并通过更色的引用修改它,主要是通过添加元素“黄色”。

<!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>

Example 3: Function Reference Type

在此示例中,我们创建了一个函数 greet,其引用最初分配给 greetingFunction。在使用它来打招呼后,我们修改引用以指向另一个函数,用 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>

Example 4: Custom class

此示例从引用类型的角度演示了 JavaScript 中的自定义类,这是另一个关键方面。该类由属性和函数/方法组成。在这里,我们创建了一个带有构造函数和方法的类 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>

Example 5: Immutable Objects

此示例重点介绍使用 Object.freeze() 创建对象时实现的对象不可变性。不可变性基本上意味着创建后对象不会更改,或者只是确保一旦定义了对象,就无法修改其属性。在这里,我们创建一个带有 name 和 age 作为属性的 person 对象,然后再尝试将 age 更改为 35。但是,对象冻结状态阻止了此修改并引发错误。不可变性作为一个重要方面,因为它有助于维护数据完整性,从而防止意外更改并增强了代码执行的可预测性。<br>

<!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>