Skip to content

Instantly share code, notes, and snippets.

@digitalconceptvisuals
Last active July 30, 2020 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digitalconceptvisuals/6733b7ec3c6e07051483d1ef501b10f6 to your computer and use it in GitHub Desktop.
Save digitalconceptvisuals/6733b7ec3c6e07051483d1ef501b10f6 to your computer and use it in GitHub Desktop.
// Needed to check isProxy
const util = require('util');
// Quick and Dirty Type Finder
const type = (obj) =>
obj.__proto__.constructor.name;
// Switch-offable debug
debug = console.log;
// Helpers
const isArray = (obj)
=> type(obj) == "Array";
const isObject = (obj)
=> type(obj) == "Object";
const isFunction = (obj)
=> type(obj) == "Function";
const isProxy = (obj)
=> util.types.isProxy(obj);
const isComplex = (obj) =>
isArray(obj) ||
isObject(obj) ||
isFunction(obj) ||
isProxy(obj)
const isSimple = (obj)
=> !isComplex(obj)
// Convert back to POJSO
// Deep clone Auto object
function deepClone(inputObject) {
// Do we have a leaf element?
if (isSimple(inputObject))
return inputObject;
// We have either array or nested object
let outputObject =
type(inputObject) == "Array"
? []
: {};
// If it's an array
// Even empty slots of Array(n)
if (isArray(inputObject)) {
for (let element = 0;
element < inputObject.length;
element++) {
let value = inputObject[element];
// Either recursively clone array/object
// Or simply copy native types
outputObject[element] =
isArray(inputObject) || isObject(inputObject)
? deepClone(value)
: value;
}
}
// If it's an object
else {
for (let element in inputObject) {
let value = inputObject[element];
outputObject[element] =
isArray(inputObject) || isObject(inputObject)
? deepClone(value)
: value;
}
}
// We are ready with POJSO
return outputObject;
}
// Support added for Array vivification
// If elements is non 0, it creates an array of objects
// otherwise creates a single object
function Auto(elements) {
// Convert to plain old javascript object
function toObject() {
return deepClone(this);
}
if (elements != undefined && elements > 0) {
// If called as Auto(n)
// Create array on n AutoVivs
return new Proxy(new Array(elements),
{
get: (obj, prop) => {
if (prop == 'toObject')
return toObject;
if (prop >= obj.length)
return undefined;
if (obj[prop] === undefined)
obj[prop] = Auto();
return obj[prop];
}
}
)
} else {
// If called as Auto()
// Create a single AutoViv object
return new Proxy({},
{
// Handler checks if prop does not exists, creates it
get: (obj, prop) => {
if (prop == 'toObject')
return toObject;
return (prop in obj
? obj[prop]
: obj[prop] = Auto());
}
}
)
}
}
let univ = Auto();
univ.college.stream.year = "A+";
univ.college.stream.subjects = Auto(3);
univ.college.stream.subjects[0].name = "JavaScript";
univ.college.stream.subjects[0].marks = 33;
console.log(univ);
console.log(univ.toObject());
console.log(univ.college.stream.subjects);
console.log(univ.college.stream.subjects.toObject());
/* Output
{ college: { stream: { year: 'A+', subjects: [Array] } } }
{ college: { stream: { year: 'A+', subjects: [Array] } } }
[ { name: 'JavaScript', marks: 33 }, {}, {} ]
[ { name: 'JavaScript', marks: 33 }, {}, {} ]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment