mirror of
https://github.com/alrayyes/wiki.git
synced 2025-07-18 15:23:27 +00:00
Quartz sync: May 6, 2024, 10:40 PM
This commit is contained in:
parent
aee9145691
commit
4ef8371441
635 changed files with 22281 additions and 6 deletions
92
content/20201022095438-javascript_metaprogramming.md
Normal file
92
content/20201022095438-javascript_metaprogramming.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
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, you’d 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.
|
Loading…
Add table
Add a link
Reference in a new issue