Что делает объект Reflect в JavaScript?
Я видел пустой заглушку на MDN некоторое время назад для Reflect
объект в javascript, но я не могу для жизни меня найти что-нибудь на Google. Сегодня я нашел это http://people.mozilla.org/~jorendorff / es6-draft.html#sec-reflect-object и это звучит похоже на прокси-объект, кроме функциональности realm и loader.
в принципе, я не знаю, объясняет ли эта страница, которую я нашел, только как реализовать Reflect или если я просто не могу понять ее формулировку. Мог кто-нибудь пожалуйста объясните мне вообще какие методы Reflect
делать?
например, на странице, которую я нашел, говорится, что вызов Reflect.apply ( target, thisArgument, argumentsList )
will " возвращает результат вызова [[Call]] внутреннего метода target с аргументами thisArgument и args.- но чем это отличается от простого звонка target.apply(thisArgument, argumentsList)
?
обновление:
благодаря @Blue, я нашел эту страницу на вики
http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api&s=reflect
что, насколько мне известно, говорит о том, что объект reflect предоставляет версии методов всех действий, которые могут быть захвачены прокси-серверами, чтобы упростить пересылку. Но это кажется мне немного странным, так как я не вижу, как это совершенно необходимо. Но это, кажется, сделать немного больше, чем это, особенно пар, который говорит double-lifting
но это указывает на старую спецификацию прокси/
3 ответа:
обновление 2015: Как указал 7-й ' s ответ, теперь, когда ES6 (ECMAScript 2015) был завершен, теперь доступна более подходящая документация:
оригинальный ответ (для (исторического) понимания и дополнительно примеры):The
Reflection proposal
кажется, продвинулся к Проект Спецификации ECMAScript 6. Этот документ в настоящее время описываетReflect
-методы объекта и только заявляет следующее оReflect
-сам объект:Объект отражения-это один обычный объект.
Значение [[прототип]] внутреннего слота объекта отражения является стандартным встроенным объектом прототипа объекта (19.1.3).
Этот Объект отражения не является объектом функции. Он не имеет [[Construct]] внутреннего метода; невозможно использовать объект Reflect в качестве конструктора с новая оператора. Объект Reflect также не имеет внутреннего метода [[Call]]; невозможно вызвать объект Reflect как функцию.однако, есть краткое объяснение о его цели в ES Harmony:
Модуль "@reflect " обслуживает несколько цели:
- теперь, когда у нас есть модули, модуль "@reflect" является более естественным местом для многих методов отражения, ранее определенных на объекте. Для целей обратной совместимости маловероятно, что статические методы на объекте исчезнут. Однако новые методы, скорее всего, должны быть добавлены в модуль "@reflect", а не в конструктор объекта.
- естественный дом для прокси, избегая необходимости глобальной привязки Прокси.
- большинство методы в этом модуле сопоставляются один к одному на прокси-ловушки. Прокси-обработчики нуждаются в этих методах для удобной переадресации операций, как показано ниже.
Итак,Reflect
объект предоставляет ряд функций полезности, многие из которых, как представляется, перекрываются с методами ES5, определенными на глобальном объекте.однако это на самом деле не объясняет, какие существующие проблемы это намеревается решить или какая функциональность добавлена. Я подозревал, что это может быть shimmed и действительно, вышеуказанные ссылки harmony-spec на A "ненормативная, приблизительная реализация этих методов".
изучение этого кода может дать (далее) представление о его использовании, но, к счастью, есть также Вики, которая описывает ряд причин, почему объект отражения полезен:
(я скопировал (и отформатировал) следующий текст для дальнейшего использования из этого источника, поскольку они являются только примеры я мог бы найти. Кроме того, они имеют смысл, уже имеют хорошее объяснение и касаются вопроса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); // property defined successfully } catch (e) { // possible failure (and might accidentally catch the wrong exception) }
для этого:
if (Reflect.defineProperty(obj, name, desc)) { // success } else { // failure }
другие методы, которые возвращают такой логический статус успеха являются
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
чтобы вызвать функцию с переменным числом аргументов, но нет
идя по проекту документа, найденного на вики,
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
мы получаем строку о "единственном обычном объекте", которую он уточняет в проекте. Он также имеет определения функций.
Вики должна быть надежной, так как вы можете найти ссылку на нее с сайта emcascript
http://www.ecmascript.org/dev.php
Я нашел первая ссылка от google, хотя и не повезло найти его, выполнив поиск Вики напрямую.
ответ GitaarLab очень хорош, но я хотел бы отметить, что объект Reflect был полностью документирован MDN включая детали и примеры для всех его методов. Некоторые люди, вероятно, предпочтут проверить это вместо этого.