es6 类的私有属性_JavaScript ES6类中的私有属性

蓝山帝景

要扩展@loganfsmyth的回答:JavaScript中唯一真正私有的数据仍然是作用域变量。不能以与公共属性相同的方式在内部访问私有属性,但是可以使用范围变量来存储私有数据。作用域变量这里的方法是使用构造函数的作用域(它是私有的)来存储私有数据。要使方法能够访问这些私有数据,它们也必须在构造函数中创建,这意味着您要用每个实例重新创建它们。这是一个性能和内存的惩罚,但一些人认为这个惩罚是可以接受的。可以避免对不需要访问私有数据的方法进行惩罚,方法可以像往常一样将它们添加到原型中。例子:function Person(name) {

  let age = 20; // this is private

  this.name = name; // this is public

  this.greet = function () {

    // here we can access both name and age

    console.log(`name: ${this.name}, age: ${age}`);

  };}let joe = new Person('Joe');joe.greet();// here we can access name but not age作用域WeakMapWeakMap可以用来避免先前方法的性能和内存损失。WeakMaps将数据与对象(此处为实例)关联起来,使其只能使用该WeakMap进行访问。因此,我们使用作用域变量方法创建私有WeakMap,然后使用该WeakMap检索与this..这比作用域变量方法更快,因为所有实例都可以共享一个WeakMap,因此您不需要仅仅为了使它们访问自己的WeakMaps而重新创建方法。例子:let Person = (function () {

  let privateProps = new WeakMap();

  class Person {

    constructor(name) {

      this.name = name; // this is public

      privateProps.set(this, {age: 20}); // this is private

    }

    greet() {

      // Here we can access both name and age

      console.log(`name: ${this.name}, age: ${privateProps.get(this).age}`);

    }

  }

  return Person;})();let joe = new Person('Joe');joe.greet();// here we can access joe's name but not age本例使用一个对象对多个私有属性使用一个WeakMap;您还可以使用多个WeakMaps,并使用它们如下age.set(this, 20),或者编写一个小包装并以另一种方式使用它,如privateProps.set(this, 'age', 0).从理论上讲,这种方法的隐私可能会被篡改全球的行为所破坏。WeakMap对象。也就是说,所有的JavaScript都可能被破损的全局破坏。我们的代码已经建立在这样的假设之上。(这个方法也可以用Map,但是WeakMap更好是因为Map除非您非常小心,否则将产生内存泄漏,为此目的,两者在其他方面并没有什么不同。)半答案:限定范围的符号符号是一种可以用作属性名称的原语值类型。可以使用作用域变量方法创建私有符号,然后将私有数据存储在this[mySymbol].此方法的隐私可能会被侵犯Object.getOwnPropertySymbols,但做起来有点尴尬。例子:let Person = (function () {

  let ageKey = Symbol();

  class Person {

    constructor(name) {

      this.name = name; // this is public

      this[ageKey] = 20; // this is intended to be private

    }

    greet() {

      // Here we can access both name and age

      console.log(`name: ${this.name}, age: ${this[ageKey]}`);

    }

  }

  return Person;})();let joe = new Person('Joe');joe.greet();// Here we can access joe's name and, with a little effort, age. ageKey is

  // not in scope, but we can obtain it by listing all Symbol properties on// joe with `Object.getOwnPropertySymbols(joe)`.半答案:下划线旧的默认值,只需使用带有下划线前缀的公共属性。尽管在任何情况下都不是私有财产,但这种约定非常普遍,因此它很好地传达了读者应该将该财产视为私有财产,这通常会使工作完成。作为交换,我们得到了一种更容易阅读、更容易打字和更快的方法。例子:class Person {

  constructor(name) {

    this.name = name; // this is public

    this._age = 20; // this is intended to be private

  }

  greet() {

    // Here we can access both name and age

    console.log(`name: ${this.name}, age: ${this._age}`);

  }}let joe = new Person('Joe');joe.greet();// Here we can access both joe's name and age. But we know we aren't

  // supposed to access his age, which just might stop us.结语截至2017年,私人地产仍没有完美的做法。各种方法各有优缺点。作用域变量是真正的私有变量;作用域WeakMaps非常私有,比作用域变量更实用;作用域符号具有合理的私有性和合理的实用性;下划线通常具有足够的私有性和非常实用性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值