【问题标题】:ES6 class with private/protected properties具有私有/受保护属性的 ES6 类
【发布时间】:2023-03-04 12:13:01
【问题描述】:

我有一个如下的 ES6 类

class CoffeeMachine {
  constructor(power) {
    this._power = power;
  }
  get power() {
    return this._power;
  }
}

// create the coffee machine 
let coffeeMachine = new CoffeeMachine(100);

console.log(coffeeMachine);

我有 2 个问题;

  1. 对于console.log(coffeeMachine),我得到以下;
CoffeeMachine {
_power: 100,
__proto__:
power: 100
}

我可以看到“power”在 CoffeeMachine 的 proto 上,并且具有相同的值,即 100 考虑到我没有在任何地方明确设置“电源”,这是怎么发生的?

  1. 在这个例子中真的可以实现私有/受保护吗?我知道最新的 ES 中有 #privateVar,但想知道是否可以在这段代码中模拟它?

【问题讨论】:

  • 我的意思是公共,私有,受保护的概念只存在于程序员和编译器然后抱怨......计算机不在乎。如果您告诉他访问某个类的某个内存偏移量,它就会这样做...所以只要您将其视为private,只要没有错误,就应该没有问题^^。但也许试试打字稿? :)
  • @elias 鉴于 typescript 最终被编译为 js ...
  • @JonasWilms 我......不明白你的意思......就像我刚刚描述的那样。访问修饰符只是为程序员提供方向。计算机本身并不关心。而且您绝对不应该将您的安全模型或类似的东西基于访问修饰符。
  • 所以回到最初的问题,有没有办法模拟“私有”属性...我指的是这个页面以供参考javascript.info/private-protected-properties-methods
  • "这是怎么发生的?" - 取决于console.log 的实现。你是在什么环境下运行这段代码的?

标签: javascript ecmascript-6 es6-class


【解决方案1】:

getter 和 setter 是 transparent,这意味着观察者(控制台)无法区分常规属性和 getter/setter。

考虑到我没有在任何地方明确设置“电源”,这是怎么发生的?

我猜这是控制台评估对象的所有值一次,然后将这些值与拥有这些属性的相应对象相关联。否则,它必须对 getter 进行两次评估(一次用于对象,一次用于原型),并且这种行为可能是不需要的。

您可以手动评估原型上的 getter:

class See { get me() { return "now"; } }

console.log(See.prototype.me);

在这个例子中真的可以实现私有/受保护吗?

是的,在 ES6 中肯定可以在 Map 周围使用 IIFE:

 const Private = (() => {
    const priv = new WeakMap();

    return class {
      get priv() { return priv.get(this); }
      set priv(v) { priv.set(this, v); }
    };
 })();

但是,正如 cmets 中已经指出的那样,您可能不需要它。正如你所说,对于 ES2020,有私有属性。

【讨论】:

  • 我正要说... transparent rgba(0,0,0,0) 到底是什么意思? :D 也许提供 MDN 参考? ^^
  • @elias 添加了参考
  • @JonasWilms 那张地图很有趣!但我想这有点破坏了课程的目的,不是吗?.. 我肯定又爱又恨 javascript:D
  • 从未使用过。也从来不需要私有财产。没有他们我很好
  • 我认为他们很方便为程序员提供指导。这就是我一直使用打字稿的原因。
【解决方案2】:

您需要创建带有# 前缀的私有变量。示例:

class CoffeeMachine {
  #_power;
  constructor(power) {
    this.#_power = power;
  }
  get power() {
    return this.#_power;
  }
}

// create the coffee machine 
let coffeeMachine = new CoffeeMachine(100);

console.log(coffeeMachine);
console.log(coffeeMachine._power);
console.log(coffeeMachine.power);

【讨论】:

猜你喜欢
  • 2016-08-13
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2018-10-17
  • 2016-04-03
相关资源
最近更新 更多