提问人:tweb 提问时间:9/30/2023 最后编辑:tweb 更新时间:10/1/2023 访问量:79
通过自定义动态方法访问嵌套的 JavaScript 属性
Accessing nested JavaScript properties via custom dynamic method
问:
给定这个 JavaScript 对象,我想通过以“get”开头的动态方法访问它们的嵌套属性 + CamelCased 属性名称(当然,该属性必须在初始对象中定义)
据我所知,这可以通过使用代理对象 + 递归来实现,但无论如何我都需要您的输入。
此致敬意!
function Order() {
this.no = 'n1234';
this.info = {
customer: {
ID: 'c1234'
address: {
//...
shiping: {
// ...
}
}
}
}
}
var order = new Order();
// The expected result should be:
// order.no = order.getNo()
// order.info = order.getInfo()
// order.info.customer or order.info.getCustomer() or order.getInfo().customer or order.getInfo().getCustomer()
// and so on for all nested attributes
这是我准备的片段,但它似乎不适用于嵌套属性。
function createProxy(obj) {
return new Proxy(obj, {
get(target, prop) {
if (typeof target[prop] === 'object' && target[prop] !== null) {
return createProxy(target[prop]);
}
if (prop.startsWith('get')) {
const propName = prop.charAt(3).toLowerCase() + prop.slice(4);
if (target[propName] !== undefined) {
return () => target[propName];
}
}
return target[prop];
},
});
}
function Order() {
const properties = {
no: 'n1234',
info: {
customer: {
ID: 'c1234'
}
}
};
return createProxy(properties);
}
var order = new Order();
// order.getInfo().customer - { ID: 'c1234' }
// order.getInfo().getCustomer() - TypeError: order.getInfo().getCustomer is not a function"
答:
1赞
Alexander Nenashev
9/30/2023
#1
一些调整会有所帮助,主要是从调用中返回代理:getXXX()
const createProxy = (obj) => new Proxy(obj, {
get(target, prop) {
const out = () => target[prop]?.__proto__ === Object.prototype ? createProxy(target[prop]) : target[prop];
return prop.startsWith?.('get') && (prop = prop[3].toLowerCase() + prop.slice(4)) ? out : out();
},
});
function Order() {
const properties = {
no: 'n1234',
info: {
customer: {
ID: 'c1234',
title: 'Bad customer'
}
}
};
return createProxy(properties);
}
var order = new Order();
console.log(order.getInfo());
console.log(order.getInfo().getCustomer().getTitle());
console.log(order.info.getCustomer().ID);
评论
0赞
tweb
10/1/2023
谢谢!这很有用。我只看到getID()无法解析并返回undefined。无论如何,我修改了您的代码,以便获得预期的结果。
1赞
tweb
10/1/2023
#2
这是有效的解决方案。感谢 @Barmar 和 Alexander Nenashev
/**
* @param {Object} obj
* @returns {Proxy} obj
*/
function createProxy(obj) {
return new Proxy(obj, {
get(target, prop) {
function out() {
if (Object.getPrototypeOf(target[prop]) === Object.prototype) {
return createProxy(target[prop]);
} else {
return target[prop];
}
}
if (!prop.startsWith('get')) {
return out();
}
var property = prop[3] + prop.slice(4);
if (property.valueOf().toUpperCase() === property.valueOf()) {
prop = property;
return out;
} else {
prop = prop[3].toLowerCase() + prop.slice(4);
return out
}
},
});
}
function Order() {
this.no = 'n1234';
this.info = {
customer: {
ID: 'c1234',
address: {
shipping: {
ID: 's4354654'
}
}
}
}
return createProxy(this);
}
var order = new Order();
console.log(order.no) // "n1234"
console.log(order.getNo()) // "n1234"
console.log(order.info.getCustomer().getID()) // "c1234"
console.log(order.getInfo().customer.ID) // "c1234"
console.log(order.info.customer.getAddress().getShipping().ID) // "s4354654"
console.log(order.getInfo().getCustomer().address.getShipping().getID()) // "s4354654"
评论
getNo()
order.no
order