一种在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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容