JavaScript如何在类方法内部获取类的私有属性名称
简介
若要获取类实例的属性,我们可以直接使用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,这一方法就会失效。
问题场景
假设你不希望用户在类方法外直接修改name和age属性,因此将其设置为私有属性。但同时你需要一个方法实现实例之间的拷贝,由于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"
问题
有没有办法可以在类的方法内部获取到类的私有属性名称?
解答
JS原生没有可以直接获取类私有属性名称的API,这是私有字段的设计特性:本身就是为了实现强封装,故意不支持运行时动态枚举、动态访问私有属性。就算你通过特殊手段拿到了私有属性的名字符串,也没法用this['#name']这类方括号语法访问私有属性,JS语法本身不支持这种写法。
针对你需要实现clone方法的场景,最直接稳定的解决方案就是硬编码赋值,同个类的实例之间可以互相访问私有属性,直接改写clone方法即可:
clone(o) { this.#name = o.#name; this.#age = o.#age; }
如果你的类私有字段经常迭代,不想每次修改都同步改clone方法,也可以在类内部维护一份私有字段的操作映射表,不需要动态获取属性名也能实现统一处理逻辑。
内容的提问来源于stack exchange,提问作者AlexSp3
相关产品推荐
相关产品推荐

