レッスンに戻る

遅延デコレータ

重要度:5

デコレータdelay(f, ms)を作成します。これにより、fの各呼び出しがmsミリ秒ずつ遅延します。

以下に例を示します。

function f(x) {
  alert(x);
}

// create wrappers
let f1000 = delay(f, 1000);
let f1500 = delay(f, 1500);

f1000("test"); // shows "test" after 1000ms
f1500("test"); // shows "test" after 1500ms

言い換えると、delay(f, ms)は「msによって遅延された」fの亜種を返します。

上記のコードでは、fは単一の引数の関数ですが、あなたのソリューションはすべての引数とthisコンテキストを渡すべきです。

テストを含んだサンドボックスを開きます。

ソリューション

function delay(f, ms) {

  return function() {
    setTimeout(() => f.apply(this, arguments), ms);
  };

}

let f1000 = delay(alert, 1000);

f1000("test"); // shows "test" after 1000ms

ここでどのように矢印関数を使用されているかに注目してください。ご存知のとおり、矢印関数には独自のthisargumentsはありません。したがって、f.apply(this, arguments)はラッパーからthisargumentsを取得します。

通常の関数を受け渡すと、setTimeoutはそれを引数なしで呼び出し、this=window(ブラウザにいると想定)になります。

中間変数を使用することで依然として正しいthisを渡すことができますが、それには手間がかかります。

function delay(f, ms) {

  return function(...args) {
    let savedThis = this; // store this into an intermediate variable
    setTimeout(function() {
      f.apply(savedThis, args); // use it here
    }, ms);
  };

}

サンドボックスでテストを含むソリューションを開きます。