Reflect is a plain namespace object (not callable, not a constructor) with 13 static methods, one for each essential internal method: get, set, has, deleteProperty, getOwnPropertyDescriptor, defineProperty, ownKeys, getPrototypeOf, setPrototypeOf, isExtensible, preventExtensions, apply, and construct. Their names match the Proxy traps, with the same parameters, so a trap can finish with return Reflect.x(...args) to do what the language would have done.
Why use it instead of target[key] or the Object.* functions:
receiver.Reflect.get(target, key, receiver)andReflect.set(target, key, value, receiver)pass the receiver to[[Get]]and[[Set]]. It becomesthisfor a getter or setter, and it is wheresetcreates the data property.target[key]always usestarget.- Boolean results.
Reflect.defineProperty,deleteProperty,set,setPrototypeOfandpreventExtensionsreturntrueorfalsewhereObject.definePropertyand friends throw. That is exactly what a trap must return. - Functions, not syntax.
in,delete,newand spread-call become ordinary functions you can pass around.Reflect.apply(fn, thisArg, args)also works whenfn.applyhas been overwritten. - No coercion. Passing a non-object as the target throws
TypeError;Object.getPrototypeOf(1)quietly boxes it. Reflect.construct(target, args, newTarget)runs a constructor with a differentnew.target, whichnewcannot do.
A forwarding trap should pass its own receiver to Reflect.get/Reflect.set, and return the boolean.