Skip to content

Instantly share code, notes, and snippets.

@likerRr
Created February 14, 2020 07:14
Show Gist options
  • Save likerRr/dfabf2aad813ac1ec00bb177b887f387 to your computer and use it in GitHub Desktop.
Save likerRr/dfabf2aad813ac1ec00bb177b887f387 to your computer and use it in GitHub Desktop.
Allows deeply access object properties through Proxies
{
const accessor = Symbol('accessor');
function createAccessor() {
function fn() {}
fn[accessor] = true;
return new Proxy(fn, {
apply() {
return createAccessor();
},
get(target, prop) {
if (prop in target) {
return target[prop];
}
return createAccessor();
}
})
}
function optional(obj) {
const isObject = o => (typeof o === 'object' && o !== null);
if (!isObject(obj)) {
return createAccessor();
}
return new Proxy(obj, {
get(target, prop, receiver) {
if (prop in target) {
const val = target[prop];
// Check if function belongs to Object or Function
if (typeof val === 'function') {
if (prop in {} || prop in (() => {})) {
return val;
}
}
if (typeof val === 'function' || isObject(val)) {
return optional(val);
}
return val;
}
return createAccessor();
}
});
}
const isAccessor = target => target.hasOwnProperty(accessor);
const isNull = val => val === null || isAccessor(val);
const val = target => isAccessor(target) ? null : target;
class User {
constructor(name) {
this.name = name;
}
}
const user = new User('Alex');
const optionalUser = optional(user);
console.clear();
console.dir(val(optionalUser.organization.title));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment