0

I have the following code:

function delay(f, ms) {
    return new Proxy(f, {
        apply(target, thisArg, args) {
            console.log(this)
            console.log(thisArg)
            setTimeout(() => f.apply(thisArg, args), ms)
        }
    })
}

function sayHi(user) {
    alert(`Hello, ${user}!`);
}

sayHi = delay(sayHi, 3000);


let container = {
    f: sayHi
}

container.f("Paul")

Why is this inside the apply function equal to {apply: f} and not to the container object? this is the object before dot, isn't it?

user3840170
  • 26,597
  • 4
  • 30
  • 62
  • Because `apply` is a method of the handler object? The `sayHi` function and its `this` argument are passed as parameters. – Bergi May 11 '23 at 13:01
  • 1
    You probably should not use a proxy here. Just return a simple wrapper function. – Bergi May 11 '23 at 13:01

1 Answers1

1

Because that is what the specification says should happen when a proxy is used:

10.5.12 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of a Proxy exotic object O takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let handler be O.[[ProxyHandler]].
  2. If handler is null, throw a TypeError exception.
  3. Assert: Type(handler) is Object.
  4. Let target be O.[[ProxyTarget]].
  5. Let trap be ? GetMethod(handler, "apply").
  6. If trap is undefined, then
    a. Return ? Call(target, thisArgument, argumentsList).
  7. Let argArray be CreateArrayFromList(argumentsList).
  8. Return ? Call(trap, handler, « target, thisArgument, argArray »).

Or in short, the relevant things here are:

  1. Take the proxy handler object, call it handler.
  2. Take the apply method from handler, call it trap.
  3. Use Call(handler, trap, args). Where args is essentially, the list of arguments needed to use Call with the original function.

The Call from step 8. in the specifications is executing a function, where the first argument is the function to execute, the second is the value for this.

Since the ECMAScript specification says that the second value should be handler and at step 1. handler is set to the [[ProxyHandler]] then the behaviour observed falls in line with the specified behaviour.

VLAZ
  • 26,331
  • 9
  • 49
  • 67