如何在JavaScript中为类实例对象动态添加setter访问器?
实现方案
有两种常用实现方式,按需选择即可:
方式1:直接给单个实例添加setter
用JS原生Object.defineProperty()API即可实现,你给出的示例补全后可运行代码如下:
const output = document.querySelector(".output") const log = (out)=>{ output.innerHTML = out } class A { constructor(some){ this._some = some } } const myObj = new A(1) // 动态添加some属性的setter Object.defineProperty(myObj, 'some', { set(value) { log(`some属性更新为:${value}`) this._some = value }, get() { return this._some }, configurable: true, // 允许后续修改/删除该属性 enumerable: true // 允许属性被遍历 }) // 测试 myObj.some = 2 // 页面将输出更新提示
方式2:将动态添加setter的能力封装到类中
如果需要该类的所有实例都支持自身动态添加setter,可以直接把逻辑封装到类内部:
class A { constructor(some){ this._some = some } /** * 为实例动态添加setter * @param {string} propName 公开属性名 * @param {Function} setterFn setter执行逻辑 */ addSetter(propName, setterFn) { const internalProp = `_${propName}` // 初始化内部存储属性 if (!this.hasOwnProperty(internalProp)) { this[internalProp] = undefined } Object.defineProperty(this, propName, { set: setterFn, get() { return this[internalProp] }, configurable: true, enumerable: true }) } } const myObj = new A(1) // 调用实例方法动态添加count属性的setter myObj.addSetter('count', function(value) { log(`count属性更新为:${value}`) this._count = value }) // 测试 myObj.count = 10 // 页面将输出更新提示
补充说明
- 如果不需要配套的getter,可以在
Object.defineProperty的配置项中只保留set属性 - 如果你需要给类的所有实例统一添加相同的setter,直接给类原型添加即可,不需要每个实例单独设置
内容的提问来源于stack exchange,提问作者Lama's
相关产品推荐
相关产品推荐

