wiki/content/20201022095438-javascript_metaprogramming.md

94 lines
2.4 KiB
Markdown
Raw Normal View History

2024-05-06 20:40:05 +00:00
---
2024-10-30 17:34:11 +00:00
date: 2020-10-22
2024-05-06 20:40:05 +00:00
id: b866160c-ac93-45af-8faf-1fd40f002f77
title: JavaScript Metaprogramming
---
# Introduction
In programming, there are levels:
- At the *base level* (also called: *application level*), code
processes user input.
- At the *meta level*, code processes base level code.
## Examples
An example of this is
[eval](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)[^1]:
``` javascript
console.log(eval("5 + 2")); // 7
```
``` javascript
const obj = {
hello() {
console.log("Hello!");
},
};
// Meta level
for (const key of Object.keys(obj)) {
console.log(key);
}
```
All [Object.\*
methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#)
can be considered metaprogramming functionality
# Kinds of metaprogramming
Reflective metaprogramming means that a program processes itself.
Kiczales et al[^2]. \[2\] distinguish three kinds of reflective
metaprogramming:
- **Introspection:** you have read-only access to the structure of a
program.
- **Self-modification:** you can change that structure
- **Intercession:** you can define the semantics of some language
operations
## Introspection
[Object.keys()](20200826201605-objects.org::*Object.keys) performs
introspection
## self-modification
The following function `moveProperty` moves a property from a source to
a target. It performs self-modification via the bracket operator for
property access, the assignment operator and the delete operator. (In
production code, youd probably use property descriptors for this task.)
``` javascript
function moveProperty(source, propertyName, target) {
target[propertyName] = source[propertyName];
delete source[propertyName];
}
const obj1 = { prop: "abc" };
const obj2 = {};
moveProperty(obj1, "prop", obj2);
console.log(obj1); // {}
console.log(obj2); // { prop: 'abc' }
```
## intercession
ECMAScript 5 doesn't support intercession.
[Proxies](20201022094207-javascript_proxies) were created to fill that
gap.
# Footnotes
[^1]: Don't ever use eval. If you think you're a clever clogs that can
work your away around the obvious security issues, then you
especially should not use eval.
[^2]: "[The Art of the Metaobject
Protocol](http://mitpress.mit.edu/books/art-metaobject-protocol)" by
Gregor Kiczales, Jim des Rivieres and Daniel G. Bobrow. Book, 1991.