Метод вызывает функцию с новым значением this
и переданными аргументами.
Приведу немного кода и постараюсь объяснить, что происходит:
let slice = Array.prorotype.slice;
slice.call([1,2,3])
Мы скопировали ссылку на метод slice
в переменную. Далее вызываем метод. Однако, простой вызов slice([1,2,3])
отработает некорректно, поскольку метод ожидает контекст извне. В этой связи мы, используя call
, передаем нужный методу контекст и все работает.
Но я не очень хочу каждый раз передавать контекст. Поэтому делаю следующее:
slice = Function.prototype.call.bind(Array.prototype.slice);
Теперь можно вызывать метод без call
:
slice([1,2,3]);
Все работает замечательно. Но проблема в том, что я не понимаю, как. Ведь метод slice
принимает итерируемый объект в качестве this
, судя по вызову slice.call([1,2,3])
или [1,2,3].slice()
. Когда мы добавляем контекст методу call
через bind
таким способом slice = Function.prototype.call.bind(Array.prototype.slice)
мы, по идее, возвращаем обертку в которой this = Array.prototype.slice
. Ну и при следующем вызове slice([1,2,3])
я ожидаю, что выполняется такой код Function.prototype.call(Array.prototype.slice, [1,2,3])
. Тогда, каким образом это работает? В документации написано, что Function.prototype.call
принимает первым аргументом контекст, а следующими аргументы функции. Но как он знает о самой функции? Понятно, когда мы на какой-то функции вызывает call
, типа slice.call
. А когда мы делаем это через прототип? У меня одна догадка, что, когда мы вызываем функцию call
через прототип Function.prototype.call
, то первым аргументом передаем саму функцию, вторым контекст и дальше аргументы. Но я нигде не могу нагуглить информацию, которая подтверждала бы мои догадки. Подскажите, пожалуйста, как на самом деле работает этот вызов:
slice = Function.prototype.call.bind(Array.prototype.slice);
Смотрите. call - это метод, для которого this - это любая функция.
Когда вы пишите вот так:
slice.call([1,2,3])
То для метода slice
контекстом (this) становится массив [1,2,3]
, а для метода call
контекстом становится уже slice
.
То же самое можно было бы написать и вот так:
call.call(slice, [1,2,3])
Когда вы пишите call.bind(slice)
- вы фиксируете контекст для call
, теперь это slice
. А вот контекст slice
не фиксируется, он по-прежнему ожидается в аргументе.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Имеется изображение фона 50 на 50 px и холст размером 500 на 500, нужно изображениями фона заполнить весь холстКак это сделать?