我有以下代码:
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")
为什么
this
函数中的 apply
等于 {apply: f}
而不是容器对象? this
是点之前的对象,不是吗?
因为这就是规范所说的在使用代理时应该发生的情况:
10.5.12 [[通话]] (
,thisArgument
)argumentsList
代理外来对象的 [[Call]] 内部方法
接受参数O
(ECMAScript 语言值)和thisArgument
(ECMAScript 语言值列表),并返回包含 ECMAScript 语言的正常完成值或突然完成。调用时它会执行以下步骤:argumentsList
- 令
为handler
。[[ProxyHandler]]。O
- 如果
为 null,则抛出 TypeError 异常。handler
- 断言:类型(
)是对象。handler
- 令
为target
。[[ProxyTarget]]。O
- 让
成为? GetMethod(trap
, "应用").handler
- 如果
是 未定义,则trap
A。返回 ?致电(、target
、thisArgument
)。argumentsList
- 令
为 CreateArrayFromList(argArray
)。argumentsList
- 返回?致电(
,trap
, «handler
,target
,thisArgument
»).argArray
或者简而言之,这里的相关内容是:
handler
。apply
中获取 handler
方法,将其命名为 trap
。Call(handler, trap, args)
。其中 args
实质上是与原始函数一起使用 Call
所需的参数列表。Call
正在执行一个函数,其中 first 参数是要执行的函数,second 是 this
的值。由于 ECMAScript 规范规定第二个值应该是
handler
并且在步骤 1.
handler
设置为 [[ProxyHandler]],那么观察到的行为与指定的行为一致。