Учитывая, что этот вопрос был задан несколько лет назад, я постараюсь добавить к нему больше, основываясь на современных технологиях.
Начиная с ECMAScript 6, метапрограммирование теперь поддерживается в некотором смысле через Символ , Отражение и Прокси объектов.
При поиске в Интернете я нашел серию очень интересных статей на эту тему, написанных Китом Киркелем:
Метапрограммирование в ES6: символы и почему они классные
Короче говоря, символы - это новые примитивы, которые могут быть добавлены внутри объекта (практически не являясь свойствами) и очень удобны для передачи свойств метапрограммирования ему среди других. Все символы предназначены для изменения поведения существующих классов путем их изменения (Отражение в реализации).
Метапрограммирование в ES6: Часть 2 - Отражение
Короче говоря, Reflect фактически представляет собой совокупность всех тех «внутренних методов», которые были доступны исключительно через внутренние компоненты движка JavaScript, теперь представленные в одном удобном объекте. Его использование аналогично возможностям отражения в Java и C #. Они используются для обнаружения информации вашего кода на очень низком уровне (Отражение через самоанализ).
Метапрограммирование в ES6: Часть 3. Прокси
Короче говоря, Прокси - это объекты-обработчики, отвечающие за обертывание объектов и перехватывающие их поведение через ловушки (Отражение через заступничество).
Конечно, эти объекты предоставляют специфические возможности метапрограммирования, гораздо более ограничивающие по сравнению с языками метапрограммирования, но, тем не менее, могут обеспечить удобные способы базового метапрограммирования, главным образом посредством практики Отражения.
В конце стоит отметить, что стоит кое-что заметить текущая исследовательская работа по поэтапному метапрограммированию в JavaScript.