在JavaScript中使用装饰器时箭头函数和函数之间的区别
我对JavaScript有点陌生,目前正在研究动态范围如何工作。现在我明白了在JavaScript中使用装饰器时箭头函数和函数之间的区别,javascript,function,this,settimeout,arrow-functions,Javascript,Function,This,Settimeout,Arrow Functions,我对JavaScript有点陌生,目前正在研究动态范围如何工作。现在我明白了这个是如何得到它的值的。我已经阅读了所有的规则并理解了其中的大部分,但是我很难理解这段代码,它解释了在装饰器中使用箭头函数和函数之间的区别。 这是代码的链接 带有箭头函数的代码 function defer(f, ms) { return function() { //What is this? Why use apply? setTimeout(() => f.apply(this, arg
这个是如何得到它的值的。我已经阅读了所有的规则并理解了其中的大部分,但是我很难理解这段代码,它解释了在装饰器中使用箭头函数和函数之间的区别。
这是代码的链接
带有箭头函数的代码
function defer(f, ms) {
return function() {
//What is this? Why use apply?
setTimeout(() => f.apply(this, arguments), ms)
};
}
function sayHi(who) {
alert('Hello, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("John"); // Hello, John after 2 seconds
功能正常
function defer(f, ms) {
return function(...args) {
// What's the purpose of this line?
let ctx = this;
setTimeout(function() {
// Again why apply?
return f.apply(ctx, args);
}, ms);
};
}
这是我难以理解的
为什么我们在这两种情况下都使用apply
?我们不能不申请就做吗李>
如果我只是调用f
而不是使用f.apply
,会发生什么
我们使用apply
是因为setTimeOut
李>
任何解释都将不胜感激。实实在在的问题——老实说——这是你思考的好迹象
为什么我们在这两种情况下都使用apply?我们不能不申请就做吗
值得一提的是,.apply
(及其同级.bind
)来自我们没有自动绑定“this”上下文的箭头函数的时代。所以,你要知道,他们来自于更古老的时代
现在,它们的用途是什么(应用/绑定)?只有当您想分配“this”时才需要它们。在您介绍的案例中,您没有引用此
——这意味着如果您只是正常调用函数,您将得到相同的结果。这也解决了你的问题:
如果我只是调用f而不是使用f.apply,会发生什么
没什么。你也会有同样的结果
由于setTimeOut,我们使用apply吗
看起来你正在举一些你在互联网上看到的例子,但简单的回答是:是的,你会使用<由于setTimeOut的原因,代码>时应用
或绑定
。但您提供的示例隐藏了实际的教训
这是一个尝试
函数iReferenceThisForStuff(){
console.log(this.foo)
}
设置超时(iReferenceThisForStuff,10)
//…10毫秒通行证
//“未定义”被记录,因为“this”引用全局窗口对象
在上面的示例中,我们向超时传递了一个非绑定函数,并记录了window.foo
,因为-当未明确设置时-此
是对全局范围的引用。这是一种回退行为,非常奇怪——但它是如何工作的
使用.bind
和.apply
示例:
函数iReferenceThisForStuff(){
console.log(this.foo)
}
setTimeout(IRereferenceThisforStuff.bind({foo:bar}),10)
//…10毫秒通行证
//记录“bar”是因为“this”引用了传递给“.bind”的对象引用`
//你也可以做。。。
setTimeout(函数(){
返回iReferenceThisForStuff.apply({foo:“bar”},/*可能还有一些附加参数*/)
}, 10)
//你也会有同样的结果。
关于箭头函数的最后说明。它们将this
绑定为实例化它们的闭包中的this
(function () {
setTimeOut(() => { // This arrow function is instantiated in a closure where `this` is a reference to { foo: "bar" } and is automatically bound.
console.log(this.foo) // Will eventually log "bar"
})
}.bind({ foo: "bar" }))
使用apply
的目的是控制此
将是什么。因为setTimeout和setInterval调用的函数没有其this集,因此在严格模式下它将是未定义的,否则将是全局对象。延迟函数将延迟函数的this设置为与调用延迟函数时使用的this相同,因此调用方可以在延迟函数中控制this的值。“未显式设置时-这是对全局范围的引用”否,这是对全局对象本身的引用,在严格模式下,它是未定义的这实际上与作用域无关,因为它总是在当前执行上下文中解析的。除了arrow函数,当它通过词法作用域链解析为外部执行上下文的这一部分时。