Metaprogramming is the process of writing code that manipulates, generates, or analyses your application’s code. The goal is to alter the default language behavior and make your code more expressive and flexible.
When you call
instanceof checks whether an object has a prototype of the constructor function it is comparing it to, anywhere in its prototype chain.
typeof is a unary operator that returns the type of entity it receives.
Monkey patching is a type of metaprogramming. It is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code. Let’s take a look at an example.
String object provides a lot of functionality out of the box. But some niceties are not available from the
String interface alone. For example, say we want to be able to remove white spaces from strings. We can use monkey patching to augment the
And voila, now we can remove spaces from our strings!
A word of caution: while the example above might seem neat(we’re adding another useful function to our strings, right?), monkey patching is generally considered a dangerous practice, as it can make your code unpredictable. For the example above, a better approach would be to turn
removeSpaces into a separate utility method that you can call when needed.
With that said, just like any other programming technique, monkey patching does have its uses. Monkey patching can help fix a specific, known problem in a 3rd-party library rather than waiting for a formal release of a patch that may take too long to come around or might not come around at all if the library is no longer supported.
The lexical name of a function is set as the
name property by default. That
name property is not writable by default, so you’ll need to use the
Object.defineProperty() method to overwrite it.
A function’s name is used in error stack traces. When a function doesn’t have a name, the browser will display a generic placeholder such as “(anonymous function)”. Stack traces become less useful when this happens, so naming functions is a good idea, especially if you’re debugging.
Symbols are primitives created using the
Symbol constructor and are used as property keys in objects. The main advantage of using symbols is that they are guaranteed to be unique throughout the lifetime of the program, so they will never collide with other keys.
In addition to symbols that you can define in your program, the
Let’s cover a couple of well-known symbols in more detail.
Remember how we used the
instanceof operator earlier? Well, actually, you can customize the behavior of that operator using
In the above code, we are overwriting the default behavior of the
instanceof operator for our custom
Here we covered only a couple of well-known symbols. Follow this link to check out the complete list of well-known symbols available.
A proxy is a specific type of object that wraps target objects. And instead of directly interacting with the target object, your client interacts with the proxy.
When creating a proxy, you can define specific handlers, called traps, that are triggered when various operations are performed against the target. These traps can be used to intersect a wide variety of basic operations.
Proxies provide powerful metaprogramming benefits. They let you intercept and override behavior of objects without altering them. Let’s take a look at a simple example:
In the code above, we used a proxy to change the values you get when accessing fields of the
pet object. We did this by adding a trap that overwrites the object’s
Here’s the complete list of handlers available with proxies .
A keen eye might notice that the behavior of our proxy above is flawed. No matter which field we try to access, we always get the hardcoded
dog string as a value. We can fix this with
Reflect API is to forward actions called on proxy traps, and for that reason,
Reflect typically goes hand in hand with proxies.
Going back to our proxy example, we can use Reflect to make it so that we return the
dog string only when the client is trying to access the
Check out this page to get the
comprehensive list of the static fields
available via the
If you’d like to get more web development, React and TypeScript tips consider
following me on Twitter,
where I share things as I learn them.