如何在 javascript 类中模拟受保护的变量?

Posted

技术标签:

【中文标题】如何在 javascript 类中模拟受保护的变量?【英文标题】:How to simulate protected variables in javascript classes? 【发布时间】:2021-11-16 18:43:47 【问题描述】:

javascript 中模拟受保护变量的最佳方法是什么?

class Parent

    #variable; // Private variable. This is not to be public.

    constructor(value)
    
        this.#variable = value;
    


class Child extends Parent

    getNewVariable()
    
        return (1 + this.#variable); // Uncaught SyntaxError: Private field '#variable' must be declared in an enclosing class
                                     // We want #variable to be accessible without making it public.
    

由于 javascript 还不支持受保护的变量,

从扩展类中的超类访问私有变量的最佳选择是什么?

我找不到太多关于此的文档,所以任何建议都会非常有帮助。

【问题讨论】:

getter 和 setter 呢? 嗨@ClausBönnhoff:感谢您的建议。 Getter 和 setter 确实有效,但我希望减少语法糖:为每个变量编写 get variable() return this.#variable; 并不理想。但是,如果这是唯一的选择,那么它将不得不这样做。 :) 使用打字稿。 受保护的属性本质上是公共的,因为每个人都可以扩展类。因此,首先将其公开。不要尝试模拟不同的语言,而是编写惯用的 JavaScript。 【参考方案1】:

+++ 迟到的答案,但我们开始... +++

基于WeakMap 的方法很可能涵盖了 OP 正在寻找的内容...

const protectedStatesMap = new WeakMap;

class Parent
  constructor(foo) 
    protectedStatesMap.set(this,  foo );
  
  getFoo() 
    return protectedStatesMap.get(this).foo;
  

class Child extends Parent
  constructor(foo, bar) 
    super(foo);

    Object.assign(protectedStatesMap.get(this),  bar )
  
  getBar() 
    return protectedStatesMap.get(this).bar;
  

const childA = new Child('foo', 'bar');
const childB = new Child('baz', 'biz');

console.log('childA.getFoo() ...', childA.getFoo());
console.log('childA.getBar() ...', childA.getBar());

console.log('childB.getFoo() ...', childB.getFoo());
console.log('childB.getBar() ...', childB.getBar());
.as-console-wrapper  min-height: 100%!important; top: 0; 

【讨论】:

@AndrewKhassapov ...查看这个迟到的答案的上述解决方案。 谢谢@PeterSeliger!【参考方案2】:

使用 TypeScript 怎么样? TypeScript 类支持 protected 关键字 (see docs),并且比原生 JavaScript 有很多额外的好处。

【讨论】:

以上是关于如何在 javascript 类中模拟受保护的变量?的主要内容,如果未能解决你的问题,请参考以下文章

C#:在密封类中模拟和测试受保护(或私有)方法——方法

ES6 类中的受保护属性(使用符号?)

C++ - 在派生类中静态初始化基类受保护的成员变量

子类从 Java 中的父类更改受保护的变量

PHP 用于访问类中所有受保护变量的函数

函数访问类中所有受保护的变量