function safeGet(data) {
return new Proxy(() => {}, {
get(target, prop) {
if (data !== undefined && prop in data) {
const value = data[prop];
if (typeof value === 'function' && prop !== 'constructor') {
return value.bind(data);
}
return safeGet(value);
} else {
return safeGet(undefined);
}
},
apply(target, thisArg, args) {
if (data !== undefined) {
return data;
}
if (args.length > 0) {
return args[0];
}
return undefined;
}
});
}
// 测试
const x = safeGet({
a: 'hello',
b: { d: 'world' },
c: [-100, 200, -300],
});
console.log(x.a() === 'hello');
console.log(x.b.d() === 'world');
console.log(x.c[0]() === -100);
console.log(x.c[100]() === undefined);
console.log(x.c[100](1234) === 1234);
console.log(JSON.stringify(x.c.map((e) => e())) === JSON.stringify([-100, 200, -300]));
console.log(x.d.e() === undefined);
console.log(x.d.e('optional default value') === 'optional default value');
console.log(x.y.z.a.b.c.d.e.f.g.h.i.j.k() === undefined);