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!

12 Upvotes

46 comments sorted by

View all comments

35

u/javascript 9d ago

Proxy Objects (getters and setters) have been around for a while but I've yet to come across a use case where they were the right choice. They tend to work more as an escape hatch.

0

u/TheThingCreator 9d ago

In my opinion they are not useful in normal development, they are the right choice if you're building a framework and need reactivity basically. Even "magic methods" don't sound like the right choice unless you're making a framework. Using these kinds of things just adds ambiguity to your code but they are highly useful for framework development.

1

u/noeldemartin 9d ago

Yes, I agree. In fact, I've only used them in 2 projects so far: an ORM and a Vue framework. Both libraries.

However, with the right Typescript declarations, it's not that ambiguous from user land. For example, in my ORM I define the fields with Zod, and using an IDE you can go straight to the Zod definition every time you use the field. They aren't declared as "any".

In any case, it's definitely a "sharp knife" and not something I use too often. But I specially like the hack of returning a Proxy from the constructor :). I haven't seen this used anywhere else, but IMO it enables some pretty powerful patterns.

1

u/TheThingCreator 9d ago

Ya I used the proxies to make a reactivity module for an app, it works very nice but ya things can get pretty pointy