如何在javascript中获取类的私有属性名称? [复制]

Posted

技术标签:

【中文标题】如何在javascript中获取类的私有属性名称? [复制]【英文标题】:How to get private properties names of a class in javascript? [duplicate] 【发布时间】:2021-10-20 16:56:09 【问题描述】:

简介

为了获取类实例的属性,我们可以使用Object.getOwnPropertyNames() 方法,如下例所示

class People 
  constructor(name, age) 
    this.name = name;
    this.age = age;
      
  getProperties() 
    return Object.getOwnPropertyNames(this);
  

console.log(new People("John", 20).getProperties())

这确实有效,因为对象的属性是public。但如果对象的属性是private,则此方法不起作用。

问题

假设您不希望用户在类方法之外直接修改nameage 属性,因此您将它们设为私有。但是,您还希望有一种方法可以在另一个实例中复制一个实例。由于Object.getOwnPropertyNames() 不适用于私有属性,因此您无法访问密钥以使clone()

class People 
  #name; #age;
  constructor(name, age) 
    this.#name = name;
    this.#age = age;
  
  clone(o) 
    Object.getOwnPropertyNames(this).forEach(key => this[key] = o[key]);
  
  getName()  return this.#name 


p1 = new People("John", 20);
p2 = new People("", 0);

p2.clone(p1);   // Now p2 should have the same properties of p1

console.log(p2.getName());      // Prints "" and should print "John"

问题

有没有办法从类方法内部访问类的私有属性名称

【问题讨论】:

getOwnPropertyNames 不包含私有属性。您必须手动复制它们。 我不明白“有没有办法从类方法内部访问类的私有属性?”这个问题。当然有,你在getName 类方法中演示它。你也可以把copy写成this.#name = o.#name; this.#age = o.#age。如果您想询问枚举私有属性的方法,请edit您的问题。 @Bergi 感谢您的建议,已更正。是的,我想要的是获得一个具有私有属性 names 的数组(或类似数组)。 @AlexandroPalacios 很抱歉,这是不可能的。在四处寻找参考资料时,我才意识到我之前已经回答过这个问题:-) 【参考方案1】:

是的。您可以使用名为WeakMaps 的东西。你会做这样的事情:

const _name = new WeakMap();
const _age = new WeakMap();

class Person 
    constructor(name, age) 
        _name.set(this, name);
        _age.set(this, age);
    

如您所见,我们使用set 方法为特定类设置weakMap 的值。

现在,要在另一种方法中访问此值,请使用 get 方法:

const _name = new WeakMap();
const _age = new WeakMap();

class Person 
    constructor(name, age) 
        _name.set(this, name);
        _age.set(this, age);
    

    getName() 
        return _name.get(this);
    


const bob = new Person('Bob', 35); // You will not be able to access the name property by typing "bob.name".
console.log(bob.getName());

get 方法将允许您访问所提到的类的弱映射的值。

有关 WeakMaps 的更多信息,请点击here

【讨论】:

不清楚这与私有实例属性及其名称有什么关系。 哦,我没有看到关于私有实例属性的部分,我只是认为是普通属性。 对不起,我对私有实例属性不太了解,只是看起来weakMaps做同样的事情 感谢您的支持。 虽然与私钥无关,但如果有办法制作一组weakmaps我可以避免使用私有属性【参考方案2】:

只需实现返回所需参数的方法:

getParameters()
    return  name: this.#name, age: this.#age ;
    

并在clone()方法中使用如下:

clone(o) 
   const  name, age  = o.getParameters();
   this.name = name;
   this.age = age;

所以你只能通过它的方法访问对象的私有参数。如果您想要一个更通用的方法,而不列出所有参数,您可以在getParameters() 方法中使用Object.entries() 方法。

【讨论】:

是的,问题是我会有更多属性,我想自动获取它们

以上是关于如何在javascript中获取类的私有属性名称? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Python 获取类属性

私有类属性

Python 之私有属性

如何理解打字稿中的“属性'名称'在'用户'类型中是私有的”

第三次发了,反射如何获取子类属性的值

0004JDK源码分析之如何反射类的私有属性和私有方法