Задерживающий декоратор
важность: 5
Создайте декоратор delay(f, ms)
, который задерживает каждый вызов f
на ms
миллисекунд.
Например:
function
f
(
x
)
{
alert
(
x)
;
}
// создаём обёртки
let
f1000 =
delay
(
f,
1000
)
;
let
f1500 =
delay
(
f,
1500
)
;
f1000
(
"test"
)
;
// показывает "test" после 1000 мс
f1500
(
"test"
)
;
// показывает "test" после 1500 мс
Другими словами, delay(f, ms)
возвращает вариант f
с «задержкой на ms
мс».
В приведённом выше коде f
– функция с одним аргументом, но ваше решение должно передавать все аргументы и контекст this
.
Решение:
function
delay
(
f,
ms
)
{
return
function
(
)
{
setTimeout
(
(
)
=>
f
.
apply
(
this
,
arguments)
,
ms)
;
}
;
}
let
f1000 =
delay
(
alert,
1000
)
;
f1000
(
"test"
)
;
// показывает "test" после 1000 мс
Обратите внимание, как здесь используется функция-стрелка. Как мы знаем, функция-стрелка не имеет собственных this
и arguments
, поэтому f.apply(this, arguments)
берет this
и arguments
из обёртки.
Если мы передадим обычную функцию, setTimeout
вызовет её без аргументов и с this=window
(при условии, что код выполняется в браузере).
Мы всё ещё можем передать правильный this
, используя промежуточную переменную, но это немного громоздко:
function
delay
(
f,
ms
)
{
return
function
(
...
args
)
{
let
savedThis =
this
;
// сохраняем this в промежуточную переменную
setTimeout
(
function
(
)
{
f
.
apply
(
savedThis,
args)
;
// используем её
}
,
ms)
;
}
;
}