Articles

JavaScriptでのメタプログラミングの簡単な紹介

Reflection

Reflectionは、”コード生成”とは異なり、言語の基礎となる仕組みを変更するプロセスです。 リフレクションはコンパイル時または実行時に発生する可能性がありますが、JavaScriptについて話しているように実行時リフレクションに固執するため、コンパイルタイムリフレクションはできません。 しかし、ここで議論された概念は、コンパイルされた言語にも適用可能である可能性があります。

私たちは、反射がすべての言語の基礎となる仕組みを変えることについてであることを理解しているように、それは三つの主要なカテゴリ、すなわち。 イントロスペクション、執り成し、そして修正。

イントロスペクション

イントロスペクションは、プログラムを分析するプロセスです。 プログラムが何をするかを伝えることができれば、あなたの好みに従ってそれを変更することができます。 一部のプログラミング言語はコード生成やコード変更機能をサポートしていませんが、おそらくイントロスペクションを許可しています。イントロスペクションの簡単な例は、JavaScriptでtypeofinstanceoftypeofinstanceofは、lhs値がRHSクラスのインスタンスである場合、truefalseを返します。 のは、アクションでそれらを見てみましょう。p>

(紹介/イントロスペクション。上記のプログラムでは、typeofinstanceofcoercecoercevalue。 これは内省の基本的なデモンストレーションです。 しかし、メタプログラミングのために特別に設計された言語は、いくつかの強力なイントロスペクションツールを提供するかもしれません。プロパティがオブジェクトに存在するかどうかを確認するには、inNaNObjectObjectObject.isFrozen(value)valueObject.keys(value)valueオブジェクトのプロパティ名。

ES5までは、これらの演算子とこれらのメソッドを使用していました。 ES2015(ES6)では、JavaScriptはいくつかの静的メソッドを提供するReflectObjectReflectについて別のレッスンを持っているので、これらのメソッドについてはそこで議論されています。

Intercession

Intercessionは、JavaScriptプロセスに介入し、プロセスの標準的な動作を変更するプロセスです。 JavaScriptは仲介のための素晴らしいツールを提供していますそのうちの一つはProxyProxyクラスは、上記のようにオブジェクトの周りの基本的なJavaScript操作を傍受(介入)するためにES2015(ES6)で導入されましたが、はるかに良い方 私たちは、ProxyProxytargethandlerhandlerもプレーンなJavaScriptオブジェクトですが、いくつかの意味のあるフィールドがあります。 For example, handler.get would be a function that returns a custom value when target.prop (here, prop is any property) is accessed.

(introduction/proxy.js)

Proxy is a great way to provide abstractions over your not-so-public data. たとえば、上記のプログラムでは、targetgettersettersを使用するなど、ES5でもいくつかの仲介が可能でしたが、targetProxytarget)。

変更

変更は、突然変異を介してプログラムの動作を変更することを指します。 Intercessionの場合、ターゲットに害を与えることなく、ターゲットと受信者の間にインターセプトロジックを追加することによって、標準のJavaScriptプロセスをインターセー この場合の修正では、受信機に合うようにターゲット自体の動作を変更しています。

関数の実装をオーバーライドすることは、変更の良い例です。 たとえば、関数が特定の方法で動作するように設計されているが、条件付きで何か他のものをしたい場合は、自己オーバーライド関数を設計することによ 例を見てみましょう。p>

(導入/機能変更。上記の例では、新しい関数の実装で自分自身をオーバーライドする関数を作成しました。 これは変更の最も厳しい例になりますが、他の、おそらくより意味のあるユースケースがあります。p>

(はじめに/readonly-オブジェクト。上記の例では、Object.defineProperty()nameObject.freeze()メソッドを使用して、オブジェクト全体をロックして、突然変異を避けることもできます。

上記の例からできるように、いくつかの仲介は変更によって発生する可能性があります。 オブジェクトのプロパティ記述子にwritable:falsevalueOfvalueOfObjectvalueOfメソッドがあります。p>

(はじめに/valueof。上記の例でわかるように、emp1/10NaNvalueOfEmployeeemp2/10200emp2.salary200200emp3/10300valueOfemp3に直接追加しました。

上記の例のすべてのステップで、オブジェクトが標準のJavaScript操作にどのように提示されるかを介入し、その動作を好みに変更しています。 これは執り成しに過ぎない。ES2015(ES6)では、JavaScriptはsymbolSymbolobjkeyはシンボルになります。p>

var key = Symbol();var obj = {
name: 'Ross',
: 200
};console.log( obj.name ); // 'Ross'
console.log( obj ); // 200
Object.keys(obj); // obj = 300;

それらは一意であるため、偶然に重複したシンボルを作成する方法はありません。 すべての新しいシンボルは一意です(Symbol()を使用して作成されます)。p>

valueOfvalueOfstringemp3valueOfを知らない人は、”名前には何が”.

シンボルはオブジェクトキーとしても使用できるため、JavaScriptはいくつかの標準的なJavaScript操作のオブジェクトキーとして使用する必要があるいくつかのグ これらのシンボルは開発者にはよく知られているので、”よく知られたシンボル”と呼ばれています。 これらのよく知られたシンボルは、SymbolSymbol.toPrimitivevalueOfメソッドの置き換えであり、それが好ましいです。p>

(はじめに/シンボル-toPrimitive。

methodtoPrimitiveメソッドは、オブジェクトの数値を返すだけではありません。 それについての詳細を知るために記号のレッスンを読んでください。

JavaScriptは、オブジェクトの周りのデフォルトのJavaScriptの動作を傍受して変更するための多くのよく知られたシンボルを提供します。 私たちは、シンボルのレッスンでこれとシンボル一般について話します。