ES6 中CLASS 怎么定义私有变量 和私有函数?

119 阅读1分钟

在 ES6 中,class 的定义虽然强大,但对于私有变量和私有函数的支持并不直接。然而,通过以下几种方法可以实现私有变量和私有函数的效果:

  1. 命名约定(不是真正的私有变量,但开发者可以约定这些变量是私有的): 使用下划线前缀表示私有变量和私有函数。这只是一个约定,并不是真正的私有属性。

    class MyClass {
      constructor() {
        this._privateVar = 'private';
      }
    
      _privateMethod() {
        console.log('This is a private method');
      }
    
      publicMethod() {
        this._privateMethod();
        console.log(this._privateVar);
      }
    }
    
    const obj = new MyClass();
    obj.publicMethod(); // This is a private method \n private
    console.log(obj._privateVar); // private
    obj._privateMethod(); // This is a private method
    
    
  2. 使用 WeakMap: 使用 WeakMap 来存储私有变量。

    const privateVars = new WeakMap();
    class MyClass {
      constructor() {
        const privateMembers = {
          privateVar: 'private'
        };
        privateVars.set(this, privateMembers);
      }
    
      _privateMethod() {
        console.log('This is a private method');
      }
    
      publicMethod() {
        this._privateMethod();
        console.log(privateVars.get(this).privateVar);
      }
    }
    const obj = new MyClass();
    obj.publicMethod(); // This is a private method \n private
    console.log(privateVars.get(obj)); // { privateVar: 'private' }
    
  3. 使用闭包: 在构造函数中使用闭包来实现私有变量和私有函数。

class MyClass {
  constructor() {
    let privateVar = 'private';

    const privateMethod = () => {
      console.log('This is a private method');
    }

    this.publicMethod = () => {
      privateMethod();
      console.log(privateVar);
    }
  }
}

const obj = new MyClass();
obj.publicMethod(); // This is a private method \n private
console.log(obj.privateVar); // undefined
// obj.privateMethod(); // TypeError: obj.privateMethod is not a function

  1. 使用 ES2022 中的私有字段和方法(# 前缀) : 从 ES2022 开始,JavaScript 支持真正的私有字段和私有方法,可以使用 # 前缀定义。
class MyClass {
  #privateVar = 'private';

  #privateMethod() {
    console.log('This is a private method');
  }

  publicMethod() {
    this.#privateMethod();
    console.log(this.#privateVar);
  }
}

const obj = new MyClass();
obj.publicMethod(); // This is a private method \n private
console.log(obj.#privateVar); // SyntaxError: Private field '#privateVar' must be declared in an enclosing class
// obj.#privateMethod(); // SyntaxError: Private field '#privateMethod' must be declared in an enclosing class

述四种方法可以实现不同程度的私有变量和私有方法的效果,其中使用 # 前缀的方法是最新且最正宗的私有实现方式。根据你的具体需求和项目兼容性,可以选择合适的方式。