封装

Frontend SELF ZH
第 40 级 , 课程 2
可用

9.1 基本概念

封装 是面向对象编程(OOP)的一个关键概念,它允许隐藏对象实现的内部细节,并通过严格定义的接口提供对这些细节的访问。这有助于提高安全性并简化代码管理。

封装的优点:

  1. 数据隐藏:封装允许隐藏实现的内部细节,仅提供必要的方法和属性的访问。这可以防止对象被不正确使用并提高代码的安全性。
  2. 访问控制:封装允许控制对数据和方法的访问,仅通过特定的方法来改变对象的内部状态。
  3. 可维护性:封装提高了代码的维护性,因为实现的变化不会影响类的外部接口。这允许在不改变使用类的代码的情况下更改实现。
  4. 改进测试:封装允许隔离对象的内部实现,简化单元测试并减少副作用的发生概率。

在JavaScript中,封装通过方法和属性实现,从ES2022开始,也可以使用私有字段和方法。

9.2 通过闭包实现封装

在ES2022引入私有字段之前,JavaScript中的封装通常通过闭包来实现。

例子:

  • 变量count只能在createCounter函数内部访问,外部无法访问
  • 方法incrementdecrementgetCount可以与私有变量count交互
JavaScript
    
      function createCounter() {
        let count = 0; // 私有变量

        return {
          increment() {
            count++;
            console.log(count);
          },
          decrement() {
            count--;
            console.log(count);
          },
          getCount() {
            return count;
          }
        };
      }

      const counter = createCounter();
      counter.increment(); // 1
      counter.increment(); // 2
      console.log(counter.getCount()); // 2
      counter.decrement(); // 1
    
  

9.3 ES2022中的私有字段

在ES2022中引入了用#符号声明的私有字段和方法。私有字段和方法不能在类的外部被访问或修改。

例子:

  • 私有字段#name#age#符号声明
  • 方法getNamegetAgesetNamesetAge用于与私有字段交互
  • 尝试在类外部访问私有字段会导致错误
JavaScript
    
      class Person {
        #name; // 私有字段
        #age; // 私有字段

        constructor(name, age) {
          this.#name = name;
          this.#age = age;
        }

        getName() {
          return this.#name;
        }

        getAge() {
          return this.#age;
        }

        setName(name) {
          this.#name = name;
        }

        setAge(age) {
          if (age > 0) {
            this.#age = age;
          }
        }
      }

      const person = new Person('Alice', 30);
      console.log(person.getName()); // "Alice"
      console.log(person.getAge()); // 30
      person.setName('Bob');
      person.setAge(25);
      console.log(person.getName()); // "Bob"
      console.log(person.getAge()); // 25
      
      console.log(person.#name); // 错误:私有字段不可访问
    
  

9.4 私有方法

私有方法也可以用#符号声明,类外部无法访问。

例子:

  • 私有字段#balance和私有方法#logTransaction用于管理BankAccount对象的状态
  • 私有方法#logTransaction在公共方法depositwithdraw内部调用以记录交易
JavaScript
    
      class BankAccount {
        #balance;

        constructor(initialBalance) {
          this.#balance = initialBalance;
        }

        deposit(amount) {
          if (amount > 0) {
            this.#balance += amount;
            this.#logTransaction('deposit', amount);
          }
        }

        withdraw(amount) {
          if (amount > 0 && amount <= this.#balance) {
            this.#balance -= amount;
            this.#logTransaction('withdraw', amount);
          }
        }

        getBalance() {
          return this.#balance;
        }

        #logTransaction(type, amount) {
          console.log(`Transaction: ${type} ${amount}`);
        }
      }

      const account = new BankAccount(1000);
      account.deposit(500); // "Transaction: deposit 500"
      console.log(account.getBalance()); // 1500
      account.withdraw(200); // "Transaction: withdraw 200"
      console.log(account.getBalance()); // 1300
      
      account.#logTransaction('test', 100); // 错误:私有方法不可访问
    
  
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION