r/javascript 9d ago

JavaScript Magic Objects

https://noeldemartin.com/blog/programming-patterns-magic-objects

I just published a blog post to my website about a pattern I've been using for a while that I think you will find interesting (and probably very divisive!): Magic Objects.

class Parrot extends MagicObject {
    __get(property) {
        return `${property}! ${property}!`;
    }
}

const parrot = new Parrot();

console.log(parrot.foo); // "foo! foo!"
console.log(parrot.bar); // "bar! bar!"

Basically, I'm borrowing the idea of Magic Methods from PHP and porting them to JavaScript. You've probably seen something like this done with proxies before, but I still like to use some OOP in my JavaScript, and I also came up with a way to make it work nicely with TypeScript.

It may seem a bit over the top at the beginning, but I've been using this for a while and I've found it very useful.

Let me know what you think!

9 Upvotes

46 comments sorted by

View all comments

13

u/krileon 9d ago

You're borrowing a feature from PHP that us PHP developers are actively avoiding and trying to get rid of, lol. Magic = Bad.

-2

u/noeldemartin 9d ago

Well, I guess you're one of the PHP developers who don't like Laravel, then :). Which is fine, as I say in the post it's a matter of opinion/preference.

But for the PHP developers who like Laravel (like me), this is actually very similar to what Laravel's ORM is doing.

I guess you also won't enjoy one other pattern I'll share in my blog, Laravel facades in JavaScript 🙈.

8

u/krileon 9d ago

I love Laravel. You don't have to use its magic. I don't use Facades. I use proper dependency injection. I use proper typed methods and properties. Some parts of Eloquent you can't get away from, but can certainly limit the magic to the minimum.

0

u/noeldemartin 9d ago

You use Laravel without Eloquent, then? How do you interact with the database, using the query builder directly?

3

u/krileon 9d ago

Of course I use Eloquent. There's nothing I can really do about it having magic. At the very least though I add statically typed getter/setter functions to reduce the magic as much as possible. Other times I've replaced it entirely with Doctrine, which was a decent chunk of work but in my experience was worth it as I prefer object mapping over active record.