简体   繁体   中英

Why is there the Proxy «apply» trap in JS?

Proxy looks like an API to extend the way we can manipulate objects such as a making single getter for all properties. There is a Proxy trap called apply that interferes a function call. According to the documentation, this trap can be used only with functions so this trap can be implemented with a plain old JavaScript code without Proxy:

// Proxy method
const trappedFunction = new Proxy(originalFunction, {
  apply: function(target, thisArg, argumentsList) {
    console.log(thisArg, argumentsList);
    return target.apply(thisArg, argumentsList);
  }
});

// Higher order function method
var trappedFunction = function () {
  console.log(this, arguments);
  return originalFunction.apply(this, arguments);
};

As far as I know, the implementations above are identical (except the arguments value that isn't an array but can be easily converted to array).

Are the implementations really identical? Why does the "apply" trap exist? What can it give compared to the plain higher order function?

Are the implementations really identical?

I can't see any difference between them as far as runtime behavior, other than the arguments -object difference. I'd personally instead do

var trappedFunction = function (...args) {
  console.log(this, args);
  originalFunction.apply(this, args);
};

to avoid arguments anyway.

Why does the "apply" trap exist? What can it give compared to the plain higher order function?

Because you might want to use the other traps at the same time. There's no way to create a higher-order function that is also a proxy. You could technically create a higher-order function and then wrap that with a proxy but that would get complicated quickly I imagine, and then you're splitting your trap-like behavior between a proxy handler and function-wrapping logic, where an apply trap along with all the rest keeps things cleanly associated.

I'd also add that unless you absolutely know that you really must to use a proxy and can make your proxy behave just like the original object, which is a lot harder than you think, I'd stick with the higher-order function approach.

Proxy was introduced to give us object access possibilities that wasn't available before such as a single getter for any property.

Personally I'd push back on this definition. Proxy was introduced to allow for JS code to implement the behavior of a JS object itself. As a side-effect, that means that JS code needs to be able to intercept accesses to all properties, even if they don't exist, but I'd hesitate to call that the reason it was introduced. The underlying "trap"-handler approach was already defined in ECMAScript specification and JS engines already had them internally exposed to allow C++ to define how a JS object behaved, for any builtin browser APIs and things. Proxy exposes those same hooks to JS itself to allow for JS itself to implement any API you could have otherwise only implemented in C++.

No, they are not identical. Your first trappedFuncton is a proxy for originalFunction , which means that it behaves exactly like originalFunction , apart from its identity and the intercepted operations (which logs arguments and drops the return value from calls, in your example).

The second trappedFunction is a completely separate function object, whose only similarity to originalFunction is that it does the same thing when called. But trappedFunction.prototype.= originalFunction.prototype , and many more.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM