能否在不触发对象属性getter的情况下引用该属性并延迟触发?
实现延迟触发对象属性getter的方法
你说得对,直接通过_myobj["foo"]的方式存入数组必然触发getter——因为只要用.或[]访问属性,就会执行对应的getter逻辑。JavaScript本身没有原生的“指向但不读取”属性的特性,但可以通过包装手段实现类似效果,让getter在访问数组元素时才触发:
方法1:存取器包装对象
创建一个包含getter的包装对象,数组存入这个包装器,只有当你访问包装器的特定属性时,才会去读取原对象的属性并触发getter:
const _myobj = {}; const _myarray = []; let someOtherValue = 'test value'; // 定义示例值 Object.defineProperty(_myobj, "foo", { enumerable: true, configurable: true, get: () => { delete _myobj["foo"]; _myobj["foo"] = someOtherValue; return _myobj["foo"]; } }) // 包装对象,访问value时才触发原属性的getter const fooRef = { get value() { return _myobj.foo; } }; _myarray.push(fooRef); // 此时才触发原getter console.log(_myarray[0].value);
方法2:函数包装(最简方案)
虽然你提到不想直接存函数,但用箭头函数做轻量包装是最直接的方式,调用函数时才触发getter:
// 存入包装函数 _myarray.push(() => _myobj.foo); // 调用时触发getter console.log(_myarray[0]());
方法3:Proxy代理(更接近“引用”的体验)
用Proxy创建一个代理对象,拦截属性访问行为,实现更接近原生属性引用的使用方式:
const fooRef = new Proxy({}, { get(target, prop) { // 自定义触发逻辑,比如访问任意属性都返回原属性值 if (prop !== '__proto__') { return _myobj.foo; } return Reflect.get(target, prop); } }); _myarray.push(fooRef); // 访问代理对象的任意属性触发getter console.log(_myarray[0].value);
为什么直接做不到?
JavaScript中不存在“属性引用”这种独立类型:
- 当你写
_myobj.foo时,无论后续是赋值还是存入数组,这一步已经完成了属性读取操作,必然触发getter。 - 原始类型按值传递,对象类型按引用传递,但这里的属性访问已经把值(或对象引用)取出来了,无法直接绑定到原属性的“引用”上。
内容的提问来源于stack exchange,提问作者Randy Hall
相关产品推荐
相关产品推荐

