How to implement private properties on ES6 class

There is no official private property syntax in ES6, but we can emulate the implementation in several ways:

1. Naming convention

The name of the private property starts with an underscore "_", which is agreed to be a private property and should not be directly accessed externally. This approach requires no extra code, just naming the private properties in the class according to the convention. For example:

class MyClass {
    
    
  constructor() {
    
    
    this._privateProperty = '私有属性';
  }
  getPrivateProperty() {
    
    
    return this._privateProperty;
  }
}

The disadvantage of this method is that there is no substantial protection, and the outside can still obtain the value of the private attribute by directly accessing the attribute.

2. Symbol private property

Use Symbol as the key of the private property, so that the external cannot directly access the private property. For example:

const _privateKey = Symbol('私有属性');

class MyClass {
    
    
  constructor(privateValue) {
    
    
    this[_privateKey] = privateValue;
  }

  getPrivateValue() {
    
    
    return this[_privateKey];
  }
}

This method can protect private properties from being directly accessed by the outside, but if the outside knows the Symbol value, the private properties can still be accessed.

3. WeakMap private property

Use WeakMap to store private properties, and the outside cannot directly access the properties in WeakMap. For example:

const privateMap = new WeakMap();

class MyClass {
    
    
  constructor(privateValue) {
    
    
    privateMap.set(this, privateValue);
  }

  getPrivateValue() {
    
    
    return privateMap.get(this);
  }
}

This method can protect private properties from being directly accessed by the outside, and the outside cannot obtain the key of the WeakMap.

4. Closures implement private properties

Use closures to encapsulate private properties in a class, which cannot be accessed externally. For example:

class MyClass {
    
    
  constructor(privateValue) {
    
    
    this.getPrivateValue = function() {
    
    
      return privateValue;
    };
  }
}

This method can protect private properties from direct external access, but every time an instance is created, a new function will be created, which will take up additional memory space.

5. Proxy implements private attributes

Use the attribute access of the Proxy proxy class to implement private attributes. For example:

const privateHandler = {
    
    
  get(target, prop) {
    
    
    if (prop.startsWith('_')) {
    
    
      throw new Error('私有属性,禁止访问!');
    }
    return target[prop];
  },
  set(target, prop, value) {
    
    
    if (prop.startsWith('_')) {
    
    
      throw new Error('私有属性,禁止赋值!');
    }
    target[prop] = value;
    return true;
  }
};

class MyClass {
    
    
  constructor() {
    
    
    this.publicProperty = '公有属性';
    this._privateProperty = '私有属性';
    return new Proxy(this, privateHandler);
  }
}

This method can protect private properties from direct external access, and can control whether assignment is allowed. But this way requires extra code to implement.

To sum up, the above methods can all realize the private properties of the class, and which method to choose depends on the application scenario and personal preference.

Guess you like

Origin blog.csdn.net/weixin_40920953/article/details/129957085