英文:
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
apply
method fromhandler
, call ittrap
. - Use
Call(handler, trap, args)
. Whereargs
is essentially, the list of arguments needed to useCall
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论