如何在javascript类中定义公共属性?

时间:2018-02-12 00:17:03

标签: javascript class

使用ES5构造函数和原型方法,我可以添加公共(原型)属性,如下所示:

function Utils(){}
Utils.prototype.data = {};

var utils = new Utils();
console.log(utils.data);  //{}

ES6 class允许我仅在类中定义公共方法。我使用类方法构建应用程序,我不想混合构造函数和类功能。我发现的工作代码是:

class Utils(){
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}

const utils = new Utils();
console.log(utils._data); //{}

当我调用_data getter方法时,它会检查原型对象中是否存在_data属性。如果是,则返回它,否则它将启动_data属性。

这是一个好习惯吗?还有其他方法可以做得更好吗?

2 个答案:

答案 0 :(得分:0)

使data成为公共实例属性:

class Utils {
  constructor () {
    this.data = {}
  }
}

要使data成为公共静态属性,get / set可能是最好的方法:

let data = {}
class Utils {
  get _data () {
    return data
  }
  set _data (d) {
    data = d
  }
}

答案 1 :(得分:0)

我不知道您提供的代码是否是您的完整代码,但是当我运行它时,它会引发错误:

class Utils {
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}


/* TEST */
const a = new Utils();
a._data.ok = 'ok';

const b = new Utils();
console.log(b._data.ok);

如果我对您的理解正确,那么您希望Utils的所有实例共享相同的data属性。

我可以想到几种方法来做您需要的事情,但是它可能会“混合使用构造函数和类功能”(我并没有真正理解您的意思)。

1:ES5的好方法

class Utils {}
Utils.prototype.data = {};

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

2:与您的方式相同,但使用的是构造函数

class Utils {
  constructor(){
    if (!this.data)
      Utils.prototype.data = {};
  }
}

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

尽管,data属性需要在实例之间共享,但我建议您使用Object.defineProperty method将属性添加到其原型中,以使其不可写和不可配置:

Object.defineProperty(Utils.prototype, 'data', {
    value: {},
    writable: false,
    enumerable: true,
    configurable: false
});

这是为了确保不能重新分配或删除数据属性,从而最大程度地减少了错误重置数据等的可能性。

我建议使用第一种方法(使用Object.defineProperty),因为它是:

  1. 更简单
  2. 清除器
  3. 易于维护