为什么 MDN 说原型继承中不能有私有属性?

作者站长头像
站长
· 阅读数 6

MDN 说私有属性是原型继承中没有简单替代方案的特性:

为什么 MDN 说原型继承中不能有私有属性?

可是不是能用闭包写私有属性吗:

function C() {
  // 私有属性
  let value = 0;

  Object.defineProperty(this, "v", {
    get: () => value,
    set: (v: number) => value = v,
  });
}

es6 类写法:

class C2 {
  #value = 0;

  get v() {
    return this.#value;
  }
  set v(v) {
    this.#value = v;
  }
}

这两种写法有什么区别吗?

回复
1个回答
avatar
test
2024-06-26

MDN 的作者措辞还是非常严谨的,“简单替代方案”,也就是说实现类似的功能,道路将会非常曲折。你的方法已经略显曲折了,但还是没有完全模拟出私有属性该有的样子——如果使用原型链继承的话,所有子类实例的 .v 属性都会指向同一个 value

function SubC (){}
SubC.prototype = new C();

var subC1 = new SubC();
var subC2 = new SubC();

// 注意这里修改的是 subC1.v
subC1.v = 10086;

// 注意这里打印的是“没被修改”的 subC2.v
console.log(subC2.v) // 10086

不过,这并不是你的写法有问题,而是原型链继承的固有缺陷,所以这里要被迫使用构造函数继承,这就偏离了“原型链继承”的语境限制,复杂程度也更上一层楼:

function SubC1 (){
  C.call(this);
}
SubC.prototype = new C();
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容