在JavaScript中使用修饰符时,箭头函数与函数之间的区别

时间:2019-06-10 20:06:34

标签: javascript function this settimeout arrow-functions

我是JavaScript的新手,目前正在研究动态范围的工作原理。现在,我了解了this是如何获得其价值的。我已经阅读了所有规则并了解了大多数规则,但是我很难理解这段代码,这些代码解释了在装饰器中使用箭头函数和函数之间的区别。 这是代码https://javascript.info/arrow-functions的链接。

带有箭头功能的代码

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);
  };
}

这就是我难以理解的地方。

  1. 为什么在两种情况下我们都使用apply?没有申请我们就不能做到吗?
  2. 如果我简单地调用f而不使用f.apply会发生什么?
  3. 是否由于apply而使用setTimeOut

任何解释将不胜感激。

1 个答案:

答案 0 :(得分:2)

实实在在的问题-您正在思考的好兆头。

  

为什么在两种情况下我们都使用Apply?我们不能在没有申请的情况下这样做吗?

值得一提的是,.apply(及其同级.bind)是从我们没有自动绑定到“ this”上下文的箭头功能开始的。所以,只要知道-他们来自更古老的时代。

现在,它们是做什么用的(申请/绑定)?当您要分配“ this”时,您实际上只需要它们。在您介绍的情况下,您没有引用this-这意味着如果您简单地正常调用这些函数,您将得到相同的结果。这也解决了您的问题:

  

如果我简单地调用f而不是使用f.apply会发生什么?

什么都没有。您会有相同的结果。

  

由于setTimeOut,我们是否使用apply?

您似乎正在举一些在互联网上看到的示例-但简短的答案是:是的,您会使用。 .apply.bind因为setTimeOut 而出现。但是您提供的示例隐藏了实际的课程。

这是尝试。


function iReferenceThisForStuff() {
    console.log(this.foo)
}

setTimeout(iReferenceThisForStuff, 10)

// ...10ms pass

// "undefined" is logged because "this" references the global window object

在上面的示例中,我们向超时传递了一个非绑定函数,并记录了window.foo,因为-在未明确设置的情况下-this是对全局范围的引用。这是一种后备行为,非常奇怪-但这是它的工作方式。

使用.bind.apply示例:


function iReferenceThisForStuff() {
    console.log(this.foo)
}

setTimeout(iReferenceThisForStuff.bind({ foo: "bar" }), 10)

// ...10ms pass

// "bar" is logged because "this" references the object reference passed to `.bind`

// You could have also done...

setTimeout(function () {
   return iReferenceThisForStuff.apply({ foo: "bar" }, /* maybe some additional args */)
}, 10)

// and you would have the same outcome.

关于箭头功能的最后注释。它们将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" })) 一样。

Analytics.enabled = false; Analytics.initializeOnStartup = false;