英文:
Value of this inside a Proxy trap
问题
以下是翻译好的部分:
我有以下的代码:
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")
为什么apply函数内部的this等于{apply: f}而不是容器对象?this不应该是点操作符前的对象吗?
英文:
I have the following code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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")
<!-- end snippet -->
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?
答案1
得分: 1
因为这是规范所规定的代理使用时应该发生的情况:
10.5.12 [[Call]] (
thisArgument,argumentsList)代理外来对象
O的 [[Call]] 内部方法接受参数thisArgument(一个 ECMAScript 语言值)和argumentsList(一组 ECMAScript 语言值),并返回包含 ECMAScript 语言值的正常完成或突然完成。在调用时,它执行以下步骤:
- 让
handler成为O的 [[ProxyHandler]]。 - 如果
handler为 null,则抛出 TypeError 异常。 - 断言:Type(
handler) 是 Object。 - 让
target成为O的 [[ProxyTarget]]。 - 让
trap为 ? GetMethod(handler, "apply")。 - 如果
trap为 undefined,则
a. 返回 ? Call(target,thisArgument,argumentsList)。 - 让
argArray成为 CreateArrayFromList(argumentsList)。 - 返回 ? Call(
trap,handler, «target,thisArgument,argArray»)。
简而言之,在这里相关的事情是:
- 获取代理处理程序对象,称之为
handler。 - 从
handler获取apply方法,称之为trap。 - 使用
Call(handler, trap, args)。其中args本质上是用于与原始函数一起使用Call所需的参数列表。
规范中第 8 步的 Call 执行一个函数,其中 第一个 参数是要执行的函数,第二个 是 this 的值。
由于 ECMAScript 规范规定第二个值应该是 handler,而在第 1 步中 handler 被设置为 [[ProxyHandler]],因此观察到的行为符合指定的行为。
英文:
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:
- Take the proxy handler object, call it
handler. - Take the
applymethod fromhandler, call ittrap. - Use
Call(handler, trap, args). Whereargsis essentially, the list of arguments needed to useCallwith 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论