此“Javascript”代码中“This”指的是什么?

时间:2018-05-01 02:11:51

标签: javascript this

我正在学习Javascript,我对“this”关键字感到有些困惑。我理解它指的是一个对象的特定实例,如果它被调用(即如果fido = new Dog(“Fido”),那么this.method将引用它被调用的特定对象。)

但是,我在Javascript.info上遇到了问题,他们有以下解决方案来实现函数原型的延迟包装器:

Function.prototype.defer = function(ms) {
  let f = this; //*****
  return function(...args) {
    setTimeout(() => f.apply(this, args), ms); //****
  }
};

// check it
function f(a, b) {
  alert(a + b);
}

f.defer(1000)(1, 2); // shows 3 after 1 sec

我对解决方案中使用“this”感到困惑。在第一次调用中,(让f = this),它将f设置为函数的特定调用。但是,之后的2行,他们调用f.apply(this,args)。我很困惑他们为什么同时使用变量f以及实际的“this”关键字......他们所指的是什么区别?

谢谢!

编辑:练习说改变原型并不是一个好习惯,但它只是为了测试你的理解

Edit2:我也尝试过使用console.log(这个),它显示未定义。我很好奇为什么我需要它(输入“”而不是“this”实际上产生相同的结果,这就是为什么我感到困惑)

4 个答案:

答案 0 :(得分:1)

正如其他评论和答案所指出的那样,有几篇好文章可以更详细地解释“this”关键字。但回答你的问题,第一个“this”(let f = this)是指向函数f的指针,而第二个“this”(f.apply(this, args))是指向窗口对象的指针,因为setTimeout是一个函数窗口对象。

答案 1 :(得分:1)

我将在下面注释代码:

Function.prototype.defer = function(ms) {
  // The function was called via a reference to a function, so the "this"
  // pointer being captured in "f" will refer to the function that was to be 
  // deferred;
  let f = this;
  return function(...args) {
    // The "this" pointer here refers to the global window object, since
    // the anonymous function returned above didn't explicitly specify
    // a this pointer via bind or other means
    console.log(this);
    setTimeout(() => {
        // Because of the use of an arrow function, the "this" pointer here
        // refers to whatever is the "this" pointer in the containing block
        // Remember, f refers to the original function, so we're invoking it
        // here
        f.apply(this, args)
    }, ms);
  }
};

答案 2 :(得分:0)

基本上,这是因为'this'变化非常快。在setTimeout内部,它将与外部不同。你使用f(尽管大多数人会使用'self'或类似的东西)来锁定执行时特定点的'this'。

How to access the correct `this` inside a callback?非常彻底。

答案 3 :(得分:-1)

defer返回function时,this中的f.apply(this, args), ms)将引用返回的function所调用的范围。

示例:

function First () {
  this.name = 'First';
}

First.prototype.defer = function(ms) {
  const f = this;

  return function() {
     setTimeout(() => {
        console.log('Names => ', f.name, this.name);
     }, ms);
  }
}

const first = new First();

function Second() {
  this.name = 'Second';
}

const second = new Second();

second.deferby1000 = first.defer(1000);

second.deferby1000(); //姓名=> “第一”“第二”