ОБНОВЛЕНИЕ 2015:
Как указано в ответе 7 -го , теперь, когда ES6 (ECMAScript 2015) был завершен, теперь доступна более подходящая документация:
Оригинальный ответ (для (исторического) понимания и дополнительных примеров) :
Reflection proposal, Кажется, продвинулись к проекту ECMAScript 6 Спецификация . В этом документе в настоящее время Reflectописываются методы -object и говорится только о самом Reflect-object:
Объект Reflect - это простой обычный объект.
Значение внутреннего слота [[Prototype]] объекта Reflect - это стандартный встроенный объект-прототип Object (19.1.3).
Объект Reflect не является функциональным объектом. У него нет внутреннего метода [[Construct]]; невозможно использовать объект Reflect в качестве конструктора с оператором new . У объекта Reflect также нет внутреннего метода [[Call]]; невозможно вызвать объект Reflect как функцию.
Тем не менее, есть краткое объяснение его цели в ES Harmony :
Модуль «@reflect» служит нескольким целям:
- Теперь, когда у нас есть модули, модуль «@reflect» является более естественным местом для многих методов отражения, ранее определенных в Object. В целях обеспечения обратной совместимости маловероятно, что статические методы в Object исчезнут. Однако новые методы, скорее всего, следует добавлять в модуль «@reflect», а не в конструктор объекта.
- Естественный дом для прокси, избавляющий от необходимости в глобальной привязке прокси.
- Большинство методов в этом модуле однозначно сопоставляют ловушки прокси. Обработчики прокси-сервера нуждаются в этих методах для удобной пересылки операций, как показано ниже.
Итак Reflect объект предоставляет ряд служебных функций, многие из которых, по-видимому, перекрываются с методами ES5, определенными в глобальном объекте.
Однако это на самом деле не объясняет, какие существующие проблемы это намеревается решить или какие функции добавляются. Я подозревал, что это можно исправить, и действительно, приведенная выше спецификация гармонии связана с «ненормативной приблизительной реализацией этих методов» .
Изучение этого кода может дать (дальнейшее) представление о его использовании, но, к счастью, есть также вики, в которой изложен ряд причин, по которым объект Reflect полезен :
(Я скопировал (и отформатировал) следующий текст для использования в будущем. источник, так как это единственные примеры, которые я смог найти. Кроме того, они имеют смысл, уже имеют хорошее объяснение и касаются applyпримера вопроса .)
Более полезные возвращаемые значения
Многие операции в Reflectпохожи на операции ES5, определенные в Object, например, Reflect.getOwnPropertyDescriptorи Reflect.defineProperty. Однако, в то время как Object.defineProperty(obj, name, desc)будет либо возвращать, objкогда свойство было успешно определено, либо генерировать в TypeErrorпротивном случае, Reflect.defineProperty(obj, name, desc)указывается, что просто возвращает логическое значение, которое указывает, было ли свойство успешно определено. Это позволяет вам реорганизовать этот код:
try {
Object.defineProperty(obj, name, desc);
} catch (e) {
}
К этому:
if (Reflect.defineProperty(obj, name, desc)) {
} else {
}
Другие методы, которые возвращают такой логический статус успеха: Reflect.set(обновить свойство), Reflect.deleteProperty(удалить свойство), Reflect.preventExtensions(сделать объект нерасширяемым) и Reflect.setPrototypeOf(обновить ссылку на прототип объекта).
Первоклассные операции
В ES5 способ определить, определяет ли объект objопределенное имя свойства или наследует его, заключается в записи (name in obj). Аналогично, чтобы удалить свойство, используется delete obj[name]. Хотя выделенный синтаксис красив и краток, это также означает, что вы должны явно заключить эти операции в функции, если вы хотите передать операцию как первоклассное значение.
С Reflect, эти операции легко определить как функции первого класса:
Reflect.has(obj, name)является функциональным эквивалентом (name in obj)и Reflect.deleteProperty(obj, name)является функцией, которая выполняет то же самое, что иdelete obj[name].
Более надежное функциональное приложение
В ES5, когда кто-то хочет вызвать функцию fс переменным количеством аргументов, упакованных в виде массива argsи привязав thisзначение к нему obj, можно написать:
f.apply(obj, args)
Однако fможет быть объект, который намеренно или непреднамеренно определяет свой собственный applyметод. Когда вы действительно хотите убедиться, что встроенная applyфункция вызывается, обычно пишут:
Function.prototype.apply.call(f, obj, args)
Это не только многословно, но и быстро становится трудным для понимания. Теперь Reflectвы можете сделать надежный вызов функции более коротким и понятным способом:
Reflect.apply(f, obj, args)
Конструкторы с переменным аргументом
Представьте, что вы хотите вызвать функцию-конструктор с переменным количеством аргументов. В ES6, благодаря новому синтаксису распространения, можно будет писать такой код, как:
var obj = new F(...args)
В ES5 это сложнее написать, потому что можно использовать F.applyили F.callвызывать функцию только с переменным числом аргументов, но F.constructдля newфункции с переменным количеством аргументов нет функции . С Reflect, один теперь можно написать, в ES5:
var obj = Reflect.construct(F, args)
Поведение пересылки по умолчанию для ловушек прокси
При использовании Proxyобъектов для обертывания существующих объектов очень часто выполняется перехват операции, выполнение чего-либо, а затем «выполнение действия по умолчанию», которое обычно заключается в применении перехваченной операции к обернутому объекту. Например, скажем, я хочу просто регистрировать все обращения к объекту по свойствам obj:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
}
});
ReflectИ ProxyAPI , были разработаны в тандеме , так что для каждой Proxyловушки, существует соответствующий метод на Reflectтом , что «делает вещь по умолчанию». Следовательно, всякий раз, когда вы обнаруживаете, что хотите "сделать стандартную" вещь внутри обработчика Proxy, правильнее всего будет всегда вызывать соответствующий метод в Reflectобъекте:
var loggedObj = new Proxy(obj, {
get: function(target, name) {
console.log("get", target, name);
return Reflect.get(target, name);
}
});
ReflectГарантируется, что возвращаемый тип методов совместим с возвращаемым типом Proxyловушек.
Управление привязкой this для аксессоров
В ES5 довольно легко выполнить общий доступ к свойству или обновить свойство. Например:
var name = ...
obj[name]
obj[name] = value
В Reflect.getи Reflect.setметоды позволяют делать то же самое, но дополнительно принимают в качестве последнего необязательного аргумента в receiverпараметр , который позволяет явно установить this-связывающего когда свойство , что вы получите / набор аксессор:
var name = ...
Reflect.get(obj, name, wrapper)
Reflect.set(obj, name, value, wrapper)
Это иногда бывает полезно, когда вы обертываете objи хотите, чтобы любые самоотправки в аксессоре перенаправлялись в вашу оболочку, например, если objопределено как:
var obj = {
get foo() { return this.bar(); },
bar: function() { ... }
}
Вызов Reflect.get(obj, "foo", wrapper)приведет this.bar()к перенаправлению вызова на wrapper.
Избегайте наследия __proto__
В некоторых браузерах __proto__определяется как специальное свойство, предоставляющее доступ к прототипу объекта. ES5 стандартизировал новый метод Object.getPrototypeOf(obj)запроса прототипа. Reflect.getPrototypeOf(obj)делает то же самое, за исключением того, что Reflectтакже определяет соответствующий Reflect.setPrototypeOf(obj, newProto)прототип объекта. Это новый совместимый с ES6 способ обновления прототипа объекта.
Обратите внимание , что: setPrototypeOf также существует наObject (как правильно указал КНС «s комментарий )!
РЕДАКТИРОВАТЬ:
примечание (обращаясь к комментариям к Q): есть короткий и простой ответ на «Q: Модули ES6 против импорта HTML», который объясняет Realmsи Loaderобъекты.
Другое объяснение предлагается по этой ссылке :
Объект области абстрагирует понятие отдельной глобальной среды со своим собственным глобальным объектом, копией стандартной библиотеки и «внутренними компонентами» (стандартные объекты, которые не привязаны к глобальным переменным, как начальное значение Object.prototype).
Расширяемый веб : это динамический эквивалент того же происхождения
<iframe>без DOM.
Однако стоит упомянуть: все это еще в черновике, это не спецификация, выгравированная на камне! Это ES6, так что помните о совместимости с браузером!
Надеюсь это поможет!
Reflectэто просто контейнер дляRealmиLoaderобъектов, но я не знаю , что последнее сделать что- либо.