本文介绍如何通过 Proxy 构建支持任意深度嵌套对象的动态 getXXX() 链式访问机制,使 order.getInfo().getCustomer().getTitle() 等调用自然生效,同时保持原生属性访问(如 order.info.customer.ID)完全兼容。
本文介绍如何通过 proxy 构建支持任意深度嵌套对象的动态 `getxxx()` 链式访问机制,使 `order.getinfo().getcustomer().gettitle()` 等调用自然生效,同时保持原生属性访问(如 `order.info.customer.id`)完全兼容。
在现代 JavaScript 开发中,为对象提供语义化、可链式调用的 getter 方法(如 getInfo() 替代 info)能显著提升 API 可读性与封装性。但若需支持无限层级嵌套对象(如 info → customer → address → shipping),并让每一层都自动具备 getXXX() 能力,则不能仅靠静态方法或单层 Proxy —— 必须让每个 getXXX() 的返回值本身也成为一个代理对象。
核心思路是:所有对象属性访问(包括 getXXX() 返回值)都必须被代理包裹,以递归延续能力。以下是经过优化的完整实现:
const createProxy = (obj) => new Proxy(obj, {
get(target, prop) {
// 若访问的是 get 开头的方法(如 getCustomer)
if (typeof prop === 'string' && prop.startsWith('get')) {
const propName = prop[3].toLowerCase() + prop.slice(4); // getCustomer → customer
const value = target[propName];
// 若目标属性存在且为普通对象(非 null、非原始值、有 Object 原型),则返回其代理
if (value != null && typeof value === 'object' && value.__proto__ === Object.prototype) {
return createProxy(value);
}
// 否则直接返回原始值(如字符串、数字、null 等)
return value;
}
// 若访问的是原生属性(如 info、no),同样检查是否为对象并代理
if (prop in target && target[prop] != null && typeof target[prop] === 'object' && target[prop].__proto__ === Object.prototype) {
return createProxy(target[prop]);
}
// 其他情况(原始值、undefined、数组、Date 等)直接返回
return target[prop];
}
});
function Order() {
const properties = {
no: 'n1234',
info: {
customer: {
ID: 'c1234',
title: 'Bad customer',
address: {
street: '123 Main St',
shipping: {
method: 'express',
cost: 9.99
}
}
}
}
};
return createProxy(properties);
}
const order = new Order();
// ✅ 所有以下调用均有效:
console.log(order.no); // 'n1234'
console.log(order.getInfo().customer.ID); // 'c1234'
console.log(order.getInfo().getCustomer().getTitle()); // 'Bad customer'
console.log(order.getInfo().getCustomer().getAddress().getShipping().getMethod()); // 'express'
console.log(order.info.getCustomer().address.shipping.cost); // 9.99⚠️ 关键注意事项:
- createProxy 严格判断 value.__proto__ === Object.prototype 来区分普通对象与 Array、Date、RegExp 等内置类型,避免对非 Plain Object 错误代理;
- 不依赖 typeof obj === 'object'(它对 null 和数组都返回 'object'),而是结合 value != null 与原型校验;
- getXXX() 方法不显式返回函数,而是直接返回代理后的值,因此调用形式是 order.getInfo()(无括号)而非 order.getInfo()() —— 这更符合直觉且避免冗余;
- 原生属性访问(如 order.info.customer)与动态方法访问(如 order.getInfo().getCustomer())可自由混用,行为完全一致;
- 该方案不修改原始数据结构,无副作用,适合封装在类或工厂函数中复用。
总结:此代理模式将“属性访问”与“方法调用”的边界消融,让嵌套对象天然具备自我描述与可扩展的访问接口,是构建高内聚、低耦合配置对象或领域模型的理想基础。
立即学习“Java免费学习笔记(深入)”;


















