在JavaScript中使用“ this”作为函数适用

时间:2019-03-16 09:46:05

标签: javascript functional-programming

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


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

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

因此,上面的代码给出了一个错误,指出“ this.apply不是函数”。但是,如果我将(**)的行更改为

setTimeout(()=>f.apply(this, args), ms);

即使f仍引用“ this”,代码也可以正常运行。是什么赋予了?

4 个答案:

答案 0 :(得分:1)

每个function都有自己的this,与外部this不必相同。

您可以将this绑定到参数的返回函数。

此功能内部this停留,因为您采用了arrow function,而外部this则位于该位置。

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

function f(a, b) {
    console.log(a + b);
}

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

答案 1 :(得分:1)

让我们看一下问题中提供的代码,看看为什么会起作用并且 另一个没有。

我们首先来看一下功能示例:

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

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

f.defer(1000)(1, 2); // shows 3 after 1 second
// translates to
setTimeout(() => f.appy(this, [1, 2]), 1000);
//                       ^
// here `this` refers to the global object (window)

让我们看看不起作用的示例:

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

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

f.defer(1000)(1, 2); // shows 3 after 1 second
// translates to
setTimeout(() => this.appy(this, [1, 2]), 1000);
//                ^         ^
// here `this` refers to the global object (window)

由于上述上下文中的this指向全局对象(窗口),因此您可以 也写成这样:

setTimeout(() => window.appy(window, [1, 2]), 1000);

由于window是一个对象而不是一个函数,因此这说明了您的错误 得到。

答案 2 :(得分:0)

函数的this会发生变化,就像您具有与外部作用域相同的参数名(在下面的示例中为ms)一样。

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

function f(a, b) {
    console.log(a + b);
}

f.defer(100000)(1000, 1, 2); // shows 3 after 1 second (not 100 second)

答案 3 :(得分:0)

this 的用法在箭头函数和常规函数之间是不同的。对于箭头功能,它们每个都有自己的 this

但是在其他函数中使用 this 时,会有一组更复杂的规则,通常取决于从何处调用函数。如果您有兴趣,以下是这些规则的列表:https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md#review-tldr