Created
February 14, 2020 07:14
-
-
Save likerRr/dfabf2aad813ac1ec00bb177b887f387 to your computer and use it in GitHub Desktop.
Allows deeply access object properties through Proxies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
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