一种在Js中实现私有属性和方法的思路

基础知识

目前绝大多数环境已经支持Js的class关键字使用,我们几乎不用再使用ES5的构造函数方式来模拟类的使用。

// ES5 style
const Person = function(name) {
  this.name = name;
};

Person.prototype.print = function() {
  console.log(this.name);
};

const me = new Person('me')
// ES6 style
class People {
  constructor(name) {
    this.name = name;
  }
  print() {
    console.log(this.name);
  }
}

const me = new Person('me')

Proxy 可以构建一个拦截器,对对象的操作进行拦截处理。

const obj = new Proxy(
  {},
  {
    set: function(target, prop, value) {
      if (prop === 'age') {
        if (!Number.isInteger(value)) {
          throw new TypeError('age must be an integer');
        }
        if (value >= 170) {
          throw new TypeError('wtf');
        }
      }
      target[prop] = value;
    }
  }
);

obj.age = 1000; // wtf
思路

通过constructor返回一个带有拦截器的对象,来模拟私有属性和私有方法。

class Person {
  constructor(name) {
    this.name = name;
    this._sex = 'male';
    return new Proxy(this, {
      get: function(target, prop) {
        if (prop.toString().indexOf('_') === 0) {
          throw new TypeError('private method');
        }
        return target[prop];
      },
      set: function(target, prop, value) {
        if (prop.toString().indexOf('_') === 0) {
          throw new TypeError('private property');
        }
        target[prop] = value;
      }
    });
  }
  print() {
    console.log(this.name);
  }
  _change(name) {
    this.name = name;
  }
}

const me = new Person('Eric');

console.log(me._sex) // typeerror

me.print() // 'Eric'

me._change('Kevin') // typeerror

总体实现过程十分简单,不过需要对私有属性和方法的写法上有要求,不是一种完美的方法。

你可能感兴趣的:(一种在Js中实现私有属性和方法的思路)