Что делает объект 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 60

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 включая детали и примеры для всех его методов. Некоторые люди, вероятно, предпочтут проверить это вместо этого.