Fun With Proxies
You can do some nifty tricks with JS proxies to add behavior to plain objects. Below are some examples to create object literals whose properties expire. Prank your coworkers! Make your code less readable!
With Expiry
const expiryCache = (ms) => {
return new Proxy({}, {
get: function (target, property) {
if (target[property] && Date.now() < target[property].expires) {
return target[property].value;
}
return undefined;
},
set: function (target, property, value) {
target[property] = {
value,
expires: Date.now() + ms,
}
}
});
};
LRU Cache
const lruCache = (n) => {
let head = null;
let tail = null;
let size = 0;
return new Proxy({}, {
get: function (target, property) {
if (target[property]) {
if (target[property].prev) {
target[property].prev.next = target[property].next;
}
if (target[property].next) {
target[property].next.prev = target[property].prev;
}
if (tail) {
tail.next = target[property];
}
if (target[property] === head && size > 1) {
head = head.next;
}
tail = target[property];
return tail.value;
}
return undefined;
},
set: function (target, property, value) {
if (target[property]) {
if (target[property].prev) {
target[property].prev.next = target[property].next;
}
if (target[property].next) {
target[property].next.prev = target[property].prev;
}
} else {
size++;
}
target[property] = {
property,
value,
next: null,
prev: tail,
};
if (tail) {
tail.next = target[property];
}
tail = target[property];
if (size > n) {
size = n;
if (head) {
const propToDelete = head.property;
head = head.next;
delete target[propToDelete];
}
}
if (!head) {
head = target[property];
}
if (target[property] === head && size > 1) {
head = head.next;
}
}
});
};
Inspired by: https://twitter.com/kognise7/status/1631502923044716546