Size: a a a

2021 January 05

DM

Denys Mikhalenko in javascript_ru
Но это вело к трудноуловимым багам у неопытных программистов и решили это дело отключить
источник

DM

Denys Mikhalenko in javascript_ru
Как раз тогда ввели так называемый strict mode, это такой режим, где все опасные для неопытных программистов возможности js отключены, вот заодно и отключили передачу глобального контекста
источник

DM

Denys Mikhalenko in javascript_ru
Теперь когда ты просто вызываешь функцию, в this будет undefined
источник

DM

Denys Mikhalenko in javascript_ru
Но, спросите вы, как же получается, что когда ты вызываешь функцию как метод объекта, в this не undefined, а этот объект - а вот так, спека так велит )
Поэтому когда вызывается функция как метод, т.е. obj.func() то js слушается спеку и засовывает в this не undefined а этот самый obj, который идет перед точкой
источник

DM

Denys Mikhalenko in javascript_ru
Теперь вопрос - вот есть у тебя функция, вызываешь ее - а там в this лежит undefined, а ты хочешь, чтоб не undefined, как?
источник

DM

Denys Mikhalenko in javascript_ru
Есть специальные сервисные методы у прототипа Function - call и apply
источник

DM

Denys Mikhalenko in javascript_ru
Ты можешь эти специальные методы вызывать вот так
Function.prototype.call() или Function.prototype.apply()
источник

DM

Denys Mikhalenko in javascript_ru
Ну и конечно можно у любой функции их вызвать, т.к. она найдет эти методы в своем прототипе и вызовет
источник

DM

Denys Mikhalenko in javascript_ru
Ну и вот этим сервисным методам уже можно дать this
источник

DM

Denys Mikhalenko in javascript_ru
Если ты вызываешь foo(1, 2, 3) то this будет задан js
Но ты можешь вызвать ее же через сервисный метод foo.call('hello', 1, 2, 3) - в этом случае js примет первый аргумент за this и если в foo ты сделаешь console.log(this), то увидишь строку hello - которую ты и передал
источник

DM

Denys Mikhalenko in javascript_ru
С apply там все аналогично, разница лишь в форме передачи _остальных_ аргументов - они передаются не через запятую, а одним массивом. И все.
источник

DM

Denys Mikhalenko in javascript_ru
Ну и последний момент - bind - что делать, если ты хочешь этот this назначить, а вызывать функцию пока не хочешь - например передать ее как обработчик какого-то события, которое пока еще не случилось - ну тут на выручку приходит bind
источник

DM

Denys Mikhalenko in javascript_ru
Это еще один сервисный метод прототипа Function и что он делает, так это берет твою функцию и все те же this и прочие аргументы, которые ты передал
источник

DM

Denys Mikhalenko in javascript_ru
Создает новую функцию, которая вызовет твою через call или apply и передаст ей все эти аргументы
источник

DM

Denys Mikhalenko in javascript_ru
То есть условно когда ты делаешь
const bar = foo.bind('hello', 1, 2, 3)
то что делает этот bind?
а вот что
return function() {
 foo.call('hello', 1, 2, 3)
}
источник

DM

Denys Mikhalenko in javascript_ru
ну естественно все это через переменные, а не хардкодом, это я для понимания написал
источник

DM

Denys Mikhalenko in javascript_ru
там есть еще нюанс с тем, что он так же добавит еще и аргументы вызванной функции, но я это нарочно не упоминаю, чтобы не усложнять понимание
источник

w

whyamsx in javascript_ru
В принципе всё очень даже несложно особенно после таких объяснений
Офигеть конечно Денис ты объясняешь очень офигенно на самом деле, понятнее чем Владилен на ютубе
источник

DM

Denys Mikhalenko in javascript_ru
по факту там будет что-то типа
return function(...args) {
 foo.call('hello', 1, 2, 3, ...args)
}
источник

DM

Denys Mikhalenko in javascript_ru
И когда вы вызываете bar(4, 5), то на самом деле произойдет foo.call('hello', 1, 2, 3, 4, 5)
источник