This is a simple demo of how latest Bun could've implemented .as(Class)
instead of using the quite jurassic Object.create
which is slow, bloated due descriptors logic, if used at all, and incapable to play nicely with features introduced after Object.create
was even specified.
// what `as(Class)` should return
const { assign } = Object;
const asClass = new WeakMap;
const setClass = Class => {
class As extends Class {
constructor(fields) {
assign(super(), fields);
}
}
asClass.set(Class, As);
return As;
};
const as = Class => asClass.get(Class) || setClass(Class);
// a db mock for this demo
const db = {
query(_) {
return {
as(Class) {
const As = as(Class);
return {
all() {
return [
new As({ name: 'Alice' }),
new As({ name: 'Bob' }),
new As({ name: 'Chuck' }),
];
}
};
}
};
}
};
// a class for this demo
class User {
name = '';
#age = 0;
birthday() {
this.#age++;
}
toString() {
return `${this.name} is ${this.#age}`;
}
}
// an actual result
const results = db.query('SELECT name FROM users').as(User);
for (const user of results.all()) {
console.assert(user instanceof User);
console.assert(user.name !== '');
if (Math.random() < .7) user.birthday();
console.log(`${user}`);
}
If worth exploring, the
as
could take an optional second argument that indicates theinit
method to use if / when desired ...