wiki/content/20201022095438-javascript_metaprogramming.md

2.4 KiB
Raw Permalink Blame History

date id title
2020-10-22 b866160c-ac93-45af-8faf-1fd40f002f77 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 eval1:

console.log(eval("5 + 2")); // 7
const obj = {
  hello() {
    console.log("Hello!");
  },
};

// Meta level
for (const key of Object.keys(obj)) {
  console.log(key);
}

All Object.* methods can be considered metaprogramming functionality

Kinds of metaprogramming

Reflective metaprogramming means that a program processes itself. Kiczales et al2. [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() 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.)

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 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" by Gregor Kiczales, Jim des Rivieres and Daniel G. Bobrow. Book, 1991. ↩︎