Огромное спасибо за такой ценный free материал! Есть маленькая просьба, для таких новичков как я, было бы очень ценно понимать в каких случаях применять полученные знания. Пара примеров из реальной жизни.
Спасибо за урок! У меня не получилось передать дополнительные параметры в функцию bind, которые передаются массивом args. В console.log выводится undefined вместо передаваемого параметра. Получается примерно такой вывод "Person: Михаил, 22, Frontend, undefined" Можете ли подробнее объяснить как использовать доп параметры?
@@ob1chyk это по-началу сложно, просто каждый день читай статьи, гугли и ютубь, ну и пробуй свой код писать и смотри что происходит. Со временём мозг сам поймёт чо-как, будешь к этому хладнокровно относиться и молча делать всё правильно и без эмоций.
Что-то я не совсем понял. Каким образом заполняется параметр с массивом ...args в замыкании? В bind передается контекст ( объекты ) и функция. А дальше как замыкающая получает параметры ?
Мне кажется что в этом видео пропустили самый главный момент, без которого замыканий не существовало бы - вы пропустили момент создания лексического окружения, которое выполняется каждый раз при вызове функции
@@crn05 усложнять? Тебе в видосе показали примеры не объяснив как работает. При этом объяснение темы заняло бы 5 минут и уже не нужны бы были эти подливные примеры из любой статьи на 11 минут. На собесе если спросят то спросят именно в контексте окружения и т.д, а не на примеры "функции внутри функции" смотреть будут
Владилен, спасибо за классный контент - подача и материал, всё на очень высоком уровне. В некоторых комментариях здесь утверждается, что в видео идет речь о функциях высшего порядка а не о замыканиях. То что это функция высшего порядка, не отменяет тот факт , что здесь также присутствует замыкание: 1. Так как для функции внешним окружением является место, где она была объявлена, а не место где она была вызвана, то в нашем случае анонимная функция которую мы возвращаем как результат выполнения функции bind,получит в качестве ссылки на внешнее лексическое окружение, ссылку на лексическое окружение самой функции bind. При этом, эти ссылки сохраняются в так называемой куче(heap), что позволяет им, в отличии от непосредственно самой функции, выполняющейся в стеке и удаляющейся оттуда сразу после того как функция завершит свою работу, оставаться в памяти до удаления сборщиком мусора. 2. К лексическому окружению функции относятся не только ее параметры, но и аргументы. Поэтому, в нашем случае и context и fn также входят в лексическое окружение функции bind. Теперь, если: const func = bind(person1,LogPerson) то : при вызове func(), произойдет следующее: для получения context и fn функция сначала обратиться к своему лексическому окружению, так как их там нет, то она по имеющейся у неё ссылке начнёт поиск в лексическом окружении внешней функции, где она была объявлена, именно этот момент и есть замыкание. Вот мои два варианта решения задачи: Для чистоты эксперимента, сделал функционал как у оригинального bind, без явного добавления функции в параметры и чтоб совсем все было своим, функцию apply также сделал кастомной: _________________________________________________________________________ Object.prototype.myApply = function (context,args) { if(!Array.isArray(args)) throw new Error('parameter is not Array'); const tempContext = {...context, appliedFunc: this}; tempContext.appliedFunc(...args) }; Object.prototype.myBind = function (context,...args) { const boundFunc = this; return function () { boundFunc.myApply(context,args) } }; logPerson.myBind(person1)() _________________________________________________________________________ Или другой вариант, наиболее оптимальный, объединяющий эти две функции: _________________________________________________________________________ Object.prototype.myBind2 = function (context,...args) { const tempContext = {...context, boundFunc: this}; return function () { tempContext.boundFunc(...args) } } logPerson.myBind(person2)() _________________________________________________________________________
а об этом ты узнаешь если купишь курс! и там тебе дадут новое видео где раскроют твой вопрос, но не скажут ещё о чем-нибудь, об этом тебе расскажут уже в следующих купленных видео )) и так до тех пор пока ты не поумнеешь и не начнёшь читать книги по js'у))
Примеры и задачи должны решаться с замыканием проще и изящней, чем без него. Иначе вопрос "зачем" остается не раскрыт. А по механике все очень доходчиво.
Спасибо за данный плейлист, его ценность сложно переоценить, БЛАГОДАРЮ!!! Идея с задачками в конце просто отличная) Т к не хватало практики. БУДУ РАД ЕСЛИ КТО-ТО МНЕ ОБЬЯСНИТ ЗАЧЕМ В ЗАДАЧКЕ ВООБЩЕ ...args =) Только вот я не понимаю зачем в конечной задачке вообще замыкание и какие еще параметры вы собираетесь туда передавать, этого в условии задачи не было. Можно просто вот так сделать и так же будет все работать: function bind(context, fn) { return fn.apply(context) } bind(person1, logPerson) bind(person2, logPerson) Поэтому необходимости и смысла использования замыкания в данном примере к сожалению я не увидел, хотя хотелось применить как-то это знание. А тут по сути просто мы воспользовались альтернативой .bind(), вместо того, чтобы написать свою функцию. ИМХО.
10:50 Оператор Rest, а не Spread в данном случае. Spread используется для разделения коллекций на отдельные элементы, а rest, наоборот, для соединения отдельных значений в массив.
Самое интересное в замыканиях то, что я как-то всегда боялся этого слова, казалось что это какой-то хитровыдуманный и сложный программистский концепт. А когда понял что это такое, оказалось я сам неоднократно использовал его в своем коде даже не подозревая, чисто на интуитивном уровне.
Страшная тема для соло-обучения в онлайн-учебниках. В статье со скопом из "контекста", "лексического окружения" и "сборщика мусора" - можно впасть в депрессию. Напоминает мене, как меня в колледже учили "что такое транзистор" в течении целого года + курсовая по ним. Ну и тот самый страх, при мысли того, что тебе когда-то придётся его использовать. Так сильно заваливать информацией, когда это можно обьяснить так просто. Спасибо за ваш ролик. Какой же всё-таки талант - уметь обьяснять вещи просто.
Сколько уже слов было сказано об этом канале, но я не поленюсь и тоже напишу. Очень лаконично и четко, все по полочкам без воды, спасибо за труды. Привіт з України!
та ну нахуй тебе занесло!))) а що там на Шрі Ланці??? Країна третього світу!!! Я б зрозумів, аби ти із Ліхтенштейну привіт передавав, або із Швейцарії)@@VladilenMinin
Нет не все ибо замыкается область видимости родительской ф-ции, в этом и весь смысл, а не просто "функция в функции" и дочерняя ф-ция сохраняет доступ к этой видимости (переменным родительской ф-ции).
Не скажу ничего нового... Ты просто великолепен) Даешь окрепнуть в понимании нативного js так, как не делают другие и близко... На очереди приобретение курса по Node. Спасибо за все твои труды
Очень хорошо! Исчерпывающая информацию + сразу же можно выполнить самостоятельное задание и тут же его проверить. Большое спасибо автору, за возможность подтянуть свои знания!
Тема не полностью раскрыта. Замыкания это не про вызов функции внутри другой функции. Объясню на пальцах: Есть ьакая штука как лексическое окружение он же контекст. Например у нас есть глобальное лексическое окружение - это то куда мы пишем свой началтный код, оно же window. Далее, когда мы пишем свои функции, циклы и подобное у чего есть своё лексическое окружение - контекст и пишем в них также то, у чего есть своё лексическое окружение и ссылаемся во внутреннем дексическом окружении на переменную, которая находится во внешнем окружении, то после выполнения кода, когда внешнее лексическое окружение должно было быть уничтожено сборщиком мусора её замыкает наша ссылка во вложеннлй функции на переменную выше в лексическом окружении и не даёт сборщику мусора её уничтожить ЭТО И НАЗЫВАЕТСЯ ЗАМЫКАНИЕМ. Итог: вложенное лексическое окружение замыкает(удерживает) внешнее окружение от уничтожения сборщиком мусора из-за наличия ссылки на то самое окружение, поскольку оно ему нужно. Писал быстро, могут быть опечатки P.S. Дополнил и исправил некоторые моменты в комментариях.
@@kapitankrolick Исправлю тогдашнего себя. Тут Сборщик мусора никакой роли не играет, но суть остается прежней с некоторыми глубокими дополнениями. И так включая всё вышеперечисленное, кроме сборщика мусора добавлю, что при замыкании данные из внешнего лексического окружения записываются в такое свойство функции как [[Scope]] в виде объекта. Это свойство нам, простым смертным просто так недоступна, поэтому можно посмотреть дерево вызываемой функции используя console.dir(func()). И в этом свойстве [[Scope]], если наша функция замыкает переменную из внешнего лексического окружения, мы увидим такую запись: [[Scope]]: { Closure funcName: { car: 'BMW' } } Closure - это указание на замыкание, далее идёт имя той функции из чьего лексического окружения мы замкнули переменную car. Вот пример: function funcName() { const car = 'BMW' return function() { return car } }
@@kapitankrolick Минин обэясняет все так, что ничерта не понятно даже в тех темах, которые тебе уже известны и понятны. Смотри нормальных авторов и все будет понятно: ua-cam.com/video/PFmuCDHHpwk/v-deo.html&ab_channel=ProgrammingwithMosh
Сделал 2 раза, один раз не понял в чем прикол и сделал через bind. Потом посмотрел как ты решил, понял, что смысл был в том, чтобы не использовать bind. На сл. день сел, написал function bind (context, fn) { return fn.apply(context) } оно работает, и я не понял зачем ещё какие-то аргументы передавать... В общем, было прикольно подумать, но задачка должна быть явно какой-то другой)
Спасибо большое за объяснение! Но всё же не совсем понятно, зачем в данном случае нужно замыкание. Можно ведь в рамках одной функции всё сделать: function bind(context, fn) { return fn.call(context) } Какой практический смысл здесь в замыкании?
тогда ведь теряется смысл, который заложен в оригинальный bind: сначала указывается контекст, затем вызывается. Собственно, замыкание в этом случае и служит как раз для "отложенного" вызова.
Честно сказать я еще как (trainee), запутался из-за того что функция называется bind, и подумал что ты создаешь новую функцию для метода .bind и вызвав метод можно получится эту функцию, ну примерно как prototype, и только спустя час и долгих раздумий, я понял что это проссссто название функции где там так и было написано «свою функцию bind» Лучше Имена не называть именами методов свойст и так далее для страховки
Очередное видео на данном канале, которое было для меня невероятно полезным :) Плейлист "Сложный JavaScript простым языком" - лучшие материалы по JS из мной увиденных, в очередной раз хочу выразить благодарность автору! 9:33 Что касается задания с функцией bind, вот моё решение (в одну строчку): const bind = (obj, funct) => funct.bind(obj); Или же: function bind(obj, funct) { return funct.bind(obj); } P.S. Я не уверен на сто процентов, верное ли это решение (если оно в чём-то ошибочно, поправьте меня, кто знает лучше), но проверял с такими же объектами person, как и в примере, с функциями, которые принимают от 0 до 3 аргументов, и всё работает. UPD: нет, не всё! Функция bind должна быть каррируемой, тоесть должна уметь принимать аргументы как в первых скобках, так и во вторых. Посмотрите видео, которое автор рекомендует в комментарии к данному комментарию, там он всё объясняет идеально понятно.
Думаю что код написан правильно т.к. дело не в принимаемых аргументах, нет. Стрелочные ф-ции как и каррируемые могут создавать замыкание, они все же имеют доступ к содержимому родителя (по научному "лексическому окружению родителя"). Замыкание и каррирование - это разные вещи. Карррируемые ф-ции в отличии от стрелочных преобразуют ф-ции с множеством аргументов в последовательность ф-ций с одним аргументом. И спасибо за коммент, узнал что есть каррируемые ф-ции)👍
Ты лучший фронтенд блогер. И я могу обосновать это. Во-первых: за такой короткий промежуток времени ты создал огромный канал с исчерпывающей информацией по фронтенд разработке. Во-вторых: любой человек с желанием может просто внимательно смотря твои видео по порядку и выполняя вместе с тобой задачи научиться всему за кратчайшие сроки. Все это благодаря структурированности и продуманности каждого плейлиста и видео. Я боюсь представить скольких усилий это все тебе стоило. В-третьих: все видео без лишней воды, и неуместных рофлов. В-четвертых: на этом канале я не увидел ни одного видео ради видео, каждое видео отличается от другого и раскрывает разные темы. В-пятых: четкая дикция, отлично выступаешь на камеру. Ты на верном пути братан, продолжай
На мой взгляд стоило сделать немного иначе. function bind(fn) { return function(context) { fn.apply(context) } } const personData = bind(logPerson) Получили функцию, возвращающую данные любого человека.
я что-то не вкурил про аргументы. они ведь не передаются. откуда они появляются ? а с учетом первичного задания, все вообще сводится до fn.apply(context)()
Там не аргументы появились, а поля объекта из контекста. Я так понял параметры функция принимает, потому что спроектирована с запасом на разные ситуации.
По последней задачки думаю нужен апдейт: Функция bind в вашем примере создает "обертку" вокруг функции fn, которая при вызове устанавливает this в переданный контекст context. Это позволяет вам вызывать функцию fn так, как если бы она была методом объекта context. Давайте разберемся, как это работает, шаг за шагом: 1. bind принимает два аргумента: context и fn. 2. bind возвращает новую функцию, которая при вызове будет применять функцию fn к контексту context. 3. Когда возвращенная функция вызывается, она использует ...args для сбора всех переданных аргументов в массив args. 4. fn.apply(context, [args]) вызывается внутри этой функции. Метод apply используется для вызова функции fn с конкретным значением this (в данном случае context) и массивом аргументов args. В вашем конкретном случае использование ...args и [args] вокруг args не имеет смысла, поскольку logPerson не принимает никаких аргументов, и использование apply с массивом аргументов в этом случае избыточно. Это может быть полезно, если бы функция logPerson принимала дополнительные параметры. Тем не менее, чтобы функция bind работала корректно с функцией logPerson, которая не принимает аргументы, вам нужно вызвать fn.apply(context) без второго параметра или использовать пустой массив для аргументов: function bind(context, fn){ return function(){ // здесь args не нужны, так как logPerson их не принимает return fn.apply(context); // вызываем fn с контекстом context и без аргументов } } bind(person1, logPerson)(); // Person: Misha, 22, Frontend bind(person2, logPerson)(); // Person: Lena, 18, SMM Использование ...args и [args] имело бы смысл, если бы вы хотели, чтобы функция bind могла принимать и передавать любое количество аргументов в функцию fn, но в вашем текущем примере это не требуется.
Вот вам детки задачка по математике из 1 класса школьной программы. Поняли? Отлично! Вот пример из 2 класса школьной программы. А вот из 3 класса. Усвоили? Замечательно, молодцы!! А теперь поставьте видео на паузу и самостоятельно решите задачку которую дают на олимпиадах по математике для 11 класса)))))) Не можете? Сейчас вместе разберём... И на самом интересном месте вылетает реклама закрывающая треть экрана))))))))))) Владлен, моё к вам уважение! Ваши уроки хороши, но понять их порой крайне не просто.
но в целом очень нравится, у Вас реально талант объяснять простым языком. Этого сейчас очень мало на ютубе, одно бла бла бла, я понимаю что русский язык позволяет заниматься разглагольствованием, но хочется максимум понятной информации за минимальное время, у Вас пока по тем видео которым я смотрел все так, т.е. можно джуниоров натаскивать по Вашим видео :) все всё поймут. Спасибо еще раз.
я ша изучаю как работает движок js, и для меня оно чуть не так все. думаю Владилен поймет о чем я, более сложно. у меня там области видимости, ячейка памяти, чистильщик работает, в моем понимании замыкания. к чему же эту хрень то несу? да к тому, что Владилен в отличии от всех остальных, рассказал это максимально приближенно к тому, как оно работает на уровне компилятора. я аж прям залип на теме углубленного изучения js. как сел читать, сразу глобальная область видимости, потом правый и левый поиск, потом дошел до замыканий, и все второй день не могу оторваться от этой темы. ша this изучаю, как предмет динамической области видимости (просто в js лексическая)... и зашел опять в ютуб, посмотреть что да как на более легком уровне. ну и как не крути, у Владилена максимально все приближено к сложным темам, но рассказано простым языком. видно что тоже видать в свое время как и я сейчас, упарывался в глубь этого всего.))) спасибо!
Огромное спасибо! Шедевральное обьяснение с примерами. Как минимум, можно будет обьяснить на собеседовании принцип работы или написать самому, а не пытатьсчя заучивать непонятные словешки)))
Спасибо большое за урок. Только есть вопрос про последнее действие. Понятно что метод apply() должен обязательно иметь два параметра, но что имеется ввиду под массивом ...args ? не понял зачем нужно передавать внутри второй функции ещё какие-то параметры, если функция bind требует только обьект для контекста (person) и саму функцию вывода (logPerson) информации в консоли ?
Сократи еще больше. Bind замени на b, args на a. ну ты понял в общем. На собесе сразу на сеньора возьмут. Сразу будет понятно что человек умный, умеет коротко писать, стрелочки знает
Прежде изучал Питон и почему там всё было достаточно понятно: this, замыкания, декораторы, ООП. Потом забросил его и сейчас изучаю JS, и вроде те-же самые понятия, но доходит с трудом.
Владилен, пример в конце прекрасный, как и все Ваши видео, но тут, конечно, в конце задача с подвохом. Решить данную задачу таким способом, как это сделали Вы изначально тяжело, именно по причине того, что по условию изначально мы должны получить значения без вызова функции. И вроде работает без args.
Владилен, снимаю шляпу!) Прекрасно объясняешь теперь. Не то, что в курсах платных (если честно, не понимаю почему), может просто опыт преподавания растёт))) Так держать! То же и про .bind и .call.
Интересно, что при проверке решения у задачи меняются условия)) Задачки для самостоятельного решения - это хорошо, но данное задание вообще неоднозначное. решил, как и многие ниже: function bind (person, callback) { callback.call(person) }
В этом плейлисте два первых видео были просто великолепны, все чётко, ясно и понятно, но здесь что то пошло не так - тема замыкания не раскрыта, создание функции bind тоже, скорее ещё больше запутался... пошёл разбираться
Как вариант своего apply, но с добавлением свойства в объект. Возможно, символом можно нивелировать влияние: function bind(context, func) { return function () { context['f'] = func; return context.f(); } } function logPerson() { console.log(`Person: ${this.name}, ${this.age}, ${this.job}`) } const person1 = { name: 'Михаил', age: 22, job: 'Frontend' } const person2 = { name: 'Елена', age: 19, job: 'SMM' } bind(person2, logPerson)()
Если посмотреть закоментировааный код, который должен был отработать, то в нем предпологалось вызвать bind уже как функцию. А реализация оказалось иной в итоге. Ну раз был добавлен оператор spread, то надо было показать для чего это сделано, т.к. в контексте закоментированного задания это не требовалось делать. Итог, чтобы работало, как было в постановке задаче , достаточно было написать фунцию: function bind(context, fn) { return fn.call(context); }. Чтобы использовать args, вероятно надо модифицировать функцию logPerson(data), передав в нее дополнительный объект. Или как автор хотел использовать пердаваемые аргументы не понятно.
Спасибо за урок! Не понял только в конце в функции bind в возвращаемую функцию мы передаем args и их потом в метод apply. Как и где на практике мы можем передать эти аргументы в возвращаемую функцию? Сейчас функция bind работает и без этих аргументов
Отличные видео! Прямо сморишь и рад что нашел :) Приятный тон и тембр, довольно легко все воспринимается. Без лишнего, только основные моменты. Единственное что хотелось бы еще услышать в контексте плейлиста, так это о лексическом окружении, контекстах, скоупах, ивент лупе и подобных подкапотных штуках. С умением объяснять простыми словами поможет сильно начинающим в понимании JS. Лайки/звоночки нажал. Первый канал который так зашел что даже сморишь то что уже знаешь)))
Сделал так (писал на typescript): Function.prototype.myBind = function (context: object, ...args: any[]) { const newContext = { ...context, bindedFunction: this } return function () { newContext.bindedFunction(...args) } }
Все супер. Показал кучу примеров, но всё таки, что такое замыкания и как они работают ты не объяснил. Замыкания это не функция внутри другой функции!!! Цитирую К. Симпсона: "Замыканием называется способность функции запоминать свою лексическую область видимости и обращаться к ней, даже когда функция вызывается за пределами своей лексической области видимости". Я думаю это вызовет у новичков ложное чувство, что они узнали, что такое замыкания, что и видно из комментариев. Если хотите на самом деле узнать про замыкания, то очень хорошо это разжевывается в книге "Вы не знаете JS"
Повторю наверное в 10 раз, что этот плейлист не учебник, а способ дать людям понять «сложные» концепты. Чтобы у них было представление об этом и чтобы они научились этим пользоваться
Чувак у тебя один из самых годных контентов на русском языке. Мало кто может так преподать материал. Остальные в основном рассказывают тему, как ученик рассказывает выученный урок перед доской. Но на счет конкретно темы замыканий я не согласен. Важно понимать подробно как они работают. И это становится простым, когда человек проясняет для себя области видимости. Не смотря на всю простоту, даже опытные разработчики до конца не понимают, что это вообще такое. А новички просмотрев это видео придут в заблуждение и наверняка провалят собеседование по этой теме. Все кто написал, что наконец-то понял замыкание, попробуйте объяснить их самостоятельно. Я думаю, что вы убедитесь, что ничего так и не поняли.
Согласен с Радиславом Ялиловым! По комментариям видно, что многие засомневались! Аrgs реально сбил с панталыку. Да и не понятно. в чем тут замыкание то? Ну передали аргументы в функцию, а замыкание при чем? Я не критикую, я так понял и сказал. Лучше говорить чем молчать! ))) Сразу скажу, что я подписан на канал автора и звонок нажат )
Если честно задание было сложное. Возможно потому что я начинающий. Было сложно догадаться что нужно использовать создание нового массива ещё и с помощью оператора spread, хотя о нём я знал. Сложно понять почему он возвращается как аргумент в замыкающую функцию, также сложно понять почему аргументы самой функции bind сначала контекст а потом сама функция внутри bind. Вообщем если можно пожалуйста подробнее про это задание.
Спасибо за видео, вот мой вариант ответа: function bind(x) { return function () { this.name = x.name; this.age = x.age; this.job = x.job; return logPerson() } } bind(person1, logPerson)(); на ум пришло пока это, не особо знаком с apply
Разобравшись что к чему, сделал (написал) так: function bind(context, conclution) { ---> переменная context у нас привязана к person, а conclution к логу ф-ции logOerson т.к. в коде вывода bind(...) у нас указан вывод ф-ций logPerson и person1/person2, что дает нам понять привязку наших ДВУХ переменных в ф-ции bind к этим ДВУМ переменным в вызове bind. Непойму только зачем нам spread оператор, если без него все работает точно так же как и с ним (мы ведь в логе logPerson уже указываем как все должно выводится в консоль) Вопрос: это все называется замыканием из-за того, что мы вызываем ф-цию bind с указанной логикой к двум ф-циям глобальной видимости logPerson и person1/person2 повторно? Ока что это не особо понял, но за объяснение спасибо! return function(){ conclution.apply(context) } } function logPerson() { console.log(`Person: ${this.name}, ${this.age}, ${this.work}`); } const person1 = {name:'Mihail', age: 22, work: 'Fronend'} const person2 = {name:'Memoza', age: 19, work: 'SMM'} bind(person1, logPerson)() bind(person2, logPerson)()
стоило сказать, что apply или call можно было использовать при написании кастомного bind )) в остальном отличное видео
Огромное спасибо за такой ценный free материал! Есть маленькая просьба, для таких новичков как я, было бы очень ценно понимать в каких случаях применять полученные знания. Пара примеров из реальной жизни.
там как раз и были наведены примеры из реальной жизни, например urlGenerator
Исходные данные задачи в конце ролика:
function logPerson() {
// console.log(`Person: ${this.name}, ${this.age}, ${this.job}`)
// }
// const person1 = {name: 'Михаил', age: 22, job: 'Frontend'}
// const person2 = {name: 'Елена', age: 19, job: 'SMM'}
// bind(person1, logPerson)
// bind(person2, logPerson)
Нечитабельная срань же.
@@1khoth что тебе нечитабельно? условия задачи, которые достаточно скопировать и использовать для решения?
@@Ghost15NG замыкания.
Смогли сами реализовать bind? Как вам идея с практикой в конце?)
Если уж и писать свой байнд, то и эплай тогда тоже надо было свой )
@@NVsquare Без него никак)
Отличный урок! А можно же в возвращаемой функции не использовать Rest, а в apply() сразу передавать arguments?
@@andreyopanasenko8771 Лучше Array.from(arguments)
Спасибо за урок!
У меня не получилось передать дополнительные параметры в функцию bind, которые передаются массивом args. В console.log выводится undefined вместо передаваемого параметра. Получается примерно такой вывод "Person: Михаил, 22, Frontend, undefined"
Можете ли подробнее объяснить как использовать доп параметры?
Автор объяснил понятнее за 11 минут, чем Кантор, которого я полдня читал и не понял до конца!
Кантор в новой редакции совсем не сахар.
Там такая дичь. Так сложно написано(
@@ob1chyk это по-началу сложно, просто каждый день читай статьи, гугли и ютубь, ну и пробуй свой код писать и смотри что происходит. Со временём мозг сам поймёт чо-как, будешь к этому хладнокровно относиться и молча делать всё правильно и без эмоций.
@@indigosay Ты не понял, я конкретно про эту тему, а в основном там гораздо проще чем на MDN, например)
@@ob1chyk на MDN сухая инфа чисто повторить то, что ты чуть-чуть позабыл,. имхо
Ещё интересно было бы про AJAX, c практикой, короче скоро это будет топовый канал на ютубе с годными уроками по фронту))
XMLHttpRequest (XHR), AJAX, REST и тд жду!!!
В моде FETCH , Socket.io. REST API да, нужная штука.
Спасибо за видео! До момента, когда откуда-то появились ARGS было все понятно.
В конце блоки со ссылками на другие видео перекрывают экран и не видно кода.
чувак, ты же хочешь стать разработчиком. Возьми и тупо отключи рекламные блоки в панели разработчика.
@@olegonkos спасибо, чувак
@@olegonkos лучше поздно, чем никогда
@@olegonkos Это только до тих пор пока не перезагрузить страницу. Ну или селектор вкинуть в фильтры addblock
##.ytp-ce-element - да вот такой фильтр нужно добавить в addBliock и он сам зарежит эти рекомендации
Что-то я не совсем понял.
Каким образом заполняется параметр с массивом ...args в замыкании?
В bind передается контекст ( объекты ) и функция.
А дальше как замыкающая получает параметры ?
Да там ...args вообще по сути не нужен...
Должно было быть так:
function logPerson() {
console.log(`Person: ${this.name}, ${this.age}, ${this.job}`);
}
function bind(context) {
return (fn) => fn.apply(context);
}
const person1 = { name: "Михаил", age: 22, job: "Frontend" };
const person2 = { name: "Елена", age: 19, job: "SMM" };
bind(person1)(logPerson);
bind(person2)(logPerson);
Отдельное спасибо за примеры использования, не всегда понятно где и как реализовать ту, или иную особенность. 👍
Вот +++
Мне кажется что в этом видео пропустили самый главный момент, без которого замыканий не существовало бы - вы пропустили момент создания лексического окружения, которое выполняется каждый раз при вызове функции
наверное чтобы не усложнять и так сложную тему.
@@crn05 это центральный момент, на котором все работает... буквально, кроме этого ничего нет
@@crn05 усложнять? Тебе в видосе показали примеры не объяснив как работает. При этом объяснение темы заняло бы 5 минут и уже не нужны бы были эти подливные примеры из любой статьи на 11 минут. На собесе если спросят то спросят именно в контексте окружения и т.д, а не на примеры "функции внутри функции" смотреть будут
Да, про лексическое окружение как раз ни слова ни сказано, получается тема не полностью раскрыта, кто не понимает замыкания, так их и не поймет)))
Владилен, спасибо за классный контент - подача и материал, всё на очень высоком уровне.
В некоторых комментариях здесь утверждается, что в видео идет речь о функциях высшего порядка а не о замыканиях.
То что это функция высшего порядка, не отменяет тот факт , что здесь также присутствует замыкание:
1. Так как для функции внешним окружением является место, где она была объявлена, а не место
где она была вызвана, то в нашем случае анонимная функция которую мы возвращаем как результат выполнения
функции bind,получит в качестве ссылки на внешнее лексическое окружение, ссылку на лексическое окружение самой
функции bind.
При этом, эти ссылки сохраняются в так называемой куче(heap), что позволяет им, в отличии от непосредственно самой
функции, выполняющейся в стеке и удаляющейся оттуда сразу после того как функция завершит свою работу, оставаться в
памяти до удаления сборщиком мусора.
2. К лексическому окружению функции относятся не только ее параметры, но и аргументы. Поэтому, в нашем случае
и context и fn также входят в лексическое окружение функции bind.
Теперь, если:
const func = bind(person1,LogPerson)
то :
при вызове func(), произойдет следующее:
для получения context и fn функция сначала обратиться к своему лексическому окружению,
так как их там нет, то она по имеющейся у неё ссылке начнёт поиск в лексическом окружении внешней функции,
где она была объявлена, именно этот момент и есть замыкание.
Вот мои два варианта решения задачи:
Для чистоты эксперимента, сделал функционал как у оригинального bind, без явного добавления функции в параметры
и чтоб совсем все было своим, функцию apply также сделал кастомной:
_________________________________________________________________________
Object.prototype.myApply = function (context,args) {
if(!Array.isArray(args)) throw new Error('parameter is not Array');
const tempContext = {...context, appliedFunc: this};
tempContext.appliedFunc(...args)
};
Object.prototype.myBind = function (context,...args) {
const boundFunc = this;
return function () {
boundFunc.myApply(context,args)
}
};
logPerson.myBind(person1)()
_________________________________________________________________________
Или другой вариант, наиболее оптимальный, объединяющий эти две функции:
_________________________________________________________________________
Object.prototype.myBind2 = function (context,...args) {
const tempContext = {...context, boundFunc: this};
return function () {
tempContext.boundFunc(...args)
}
}
logPerson.myBind(person2)()
_________________________________________________________________________
------------- Базовая функция ------------
logPerson.bind (p1)( )
вывод:
Person: M, 22
this: {name: 'M', age: '22'}
age: "22"
name: "M"
[[Prototype]]: Object
------------- Ваш пример ------------
logPerson.myBind2 (p1)( )
вывод:
Person: M, 22
this: {name: 'M', age: '22', boundFunc: ƒ}
age: "22"
boundFunc: ƒ logPerson()
name: "M"
[[Prototype]]: Object
------------- Мой вариант я без аргументов делал, но добавить их не сложно ------------
bind (p1, logPerson)( )
вывод:
Person: M, 22
this: {f: ƒ}
f: ƒ logPerson()
[[Prototype]]: Object
age: "22"
name: "M"
[[Prototype]]: Object
Реализация, тоже думал что apply и call пользовать не положено
function bind(obj, func) {
const nobj = {f: func};
Object.setPrototypeOf(nobj, obj);
return (function() {nobj.f()});
}
А вот так легко call можно сделать
function bind(obj, func) {
const nObj = {f: func};
Object.setPrototypeOf(nObj, obj);
nObj.f();
}
А почему ни слова об областях видимости переменных во вложеных функциях? Мне кажется это тоже важно в данном контексте.
а что там поменялось ?
а об этом ты узнаешь если купишь курс! и там тебе дадут новое видео где раскроют твой вопрос, но не скажут ещё о чем-нибудь, об этом тебе расскажут уже в следующих купленных видео )) и так до тех пор пока ты не поумнеешь и не начнёшь читать книги по js'у))
@@epic3386 уже работаю в Оракле, так-что не актуально )
Мои искренние поздравления )) видимо начал читать книжки?))
@@epic3386 больше практика помогла)
Примеры и задачи должны решаться с замыканием проще и изящней, чем без него. Иначе вопрос "зачем" остается не раскрыт. А по механике все очень доходчиво.
Красавчик, видео одно за другим!
Главное не сбавлять темп)
Спасибо за данный плейлист, его ценность сложно переоценить, БЛАГОДАРЮ!!!
Идея с задачками в конце просто отличная) Т к не хватало практики.
БУДУ РАД ЕСЛИ КТО-ТО МНЕ ОБЬЯСНИТ ЗАЧЕМ В ЗАДАЧКЕ ВООБЩЕ ...args =)
Только вот я не понимаю зачем в конечной задачке вообще замыкание и какие еще параметры вы собираетесь туда передавать, этого в условии задачи не было. Можно просто вот так сделать и так же будет все работать:
function bind(context, fn) {
return fn.apply(context)
}
bind(person1, logPerson)
bind(person2, logPerson)
Поэтому необходимости и смысла использования замыкания в данном примере к сожалению я не увидел, хотя хотелось применить как-то это знание. А тут по сути просто мы воспользовались альтернативой .bind(), вместо того, чтобы написать свою функцию. ИМХО.
тоже не поняла зачем args нужен
Коротко, понятно + практика... Как итог - отличный урок. В общем как всегда.
Хочу сказать что твой контент очень крутой! Наконец то не тот контекст как объявлять и складывать переменные а именно то что нужно.
Как уже писал кто-то ранее, первые два ролика прям доходчиво, тут пример в конце выбивает из колеи понимания.
10:50 Оператор Rest, а не Spread в данном случае. Spread используется для разделения коллекций на отдельные элементы, а rest, наоборот, для соединения отдельных значений в массив.
Самое интересное в замыканиях то, что я как-то всегда боялся этого слова, казалось что это какой-то хитровыдуманный и сложный программистский концепт. А когда понял что это такое, оказалось я сам неоднократно использовал его в своем коде даже не подозревая, чисто на интуитивном уровне.
такое часто бывает, пользуешься чем-то, а оказывается у этого страшное название есть
Страшная тема для соло-обучения в онлайн-учебниках. В статье со скопом из "контекста", "лексического окружения" и "сборщика мусора" - можно впасть в депрессию. Напоминает мене, как меня в колледже учили "что такое транзистор" в течении целого года + курсовая по ним. Ну и тот самый страх, при мысли того, что тебе когда-то придётся его использовать. Так сильно заваливать информацией, когда это можно обьяснить так просто.
Спасибо за ваш ролик. Какой же всё-таки талант - уметь обьяснять вещи просто.
Сколько уже слов было сказано об этом канале, но я не поленюсь и тоже напишу.
Очень лаконично и четко, все по полочкам без воды, спасибо за труды. Привіт з України!
Привет с Шри-Ланки)
та ну нахуй тебе занесло!))) а що там на Шрі Ланці??? Країна третього світу!!! Я б зрозумів, аби ти із Ліхтенштейну привіт передавав, або із Швейцарії)@@VladilenMinin
Это талант так легко и просто объяснять вещи. Спасибо!
замыкание - функция внутри функции и все! гениально
Нет не все ибо замыкается область видимости родительской ф-ции, в этом и весь смысл, а не просто "функция в функции" и дочерняя ф-ция сохраняет доступ к этой видимости (переменным родительской ф-ции).
@@zxspectrum3352 Именно так. А утверждение замыкание это вызов функции в функции не верно
Не скажу ничего нового... Ты просто великолепен) Даешь окрепнуть в понимании нативного js так, как не делают другие и близко... На очереди приобретение курса по Node. Спасибо за все твои труды
Очень хорошо! Исчерпывающая информацию + сразу же можно выполнить самостоятельное задание и тут же его проверить. Большое спасибо автору, за возможность подтянуть свои знания!
Тема не полностью раскрыта. Замыкания это не про вызов функции внутри другой функции.
Объясню на пальцах: Есть ьакая штука как лексическое окружение он же контекст. Например у нас есть глобальное лексическое окружение - это то куда мы пишем свой началтный код, оно же window. Далее, когда мы пишем свои функции, циклы и подобное у чего есть своё лексическое окружение - контекст и пишем в них также то, у чего есть своё лексическое окружение и ссылаемся во внутреннем дексическом окружении на переменную, которая находится во внешнем окружении, то после выполнения кода, когда внешнее лексическое окружение должно было быть уничтожено сборщиком мусора её замыкает наша ссылка во вложеннлй функции на переменную выше в лексическом окружении и не даёт сборщику мусора её уничтожить ЭТО И НАЗЫВАЕТСЯ ЗАМЫКАНИЕМ.
Итог: вложенное лексическое окружение замыкает(удерживает) внешнее окружение от уничтожения сборщиком мусора из-за наличия ссылки на то самое окружение, поскольку оно ему нужно.
Писал быстро, могут быть опечатки
P.S. Дополнил и исправил некоторые моменты в комментариях.
получается лексическое окружение и контекст выполнения одно и то же? а про замыкание стало понятно после вашего комментария)
@@kapitankrolick Исправлю тогдашнего себя. Тут Сборщик мусора никакой роли не играет, но суть остается прежней с некоторыми глубокими дополнениями.
И так включая всё вышеперечисленное, кроме сборщика мусора добавлю, что при замыкании данные из внешнего лексического окружения записываются в такое свойство функции как [[Scope]] в виде объекта. Это свойство нам, простым смертным просто так недоступна, поэтому можно посмотреть дерево вызываемой функции используя console.dir(func()).
И в этом свойстве [[Scope]], если наша функция замыкает переменную из внешнего лексического окружения, мы увидим такую запись:
[[Scope]]: {
Closure funcName: {
car: 'BMW'
}
}
Closure - это указание на замыкание, далее идёт имя той функции из чьего лексического окружения мы замкнули переменную car.
Вот пример:
function funcName() {
const car = 'BMW'
return function() {
return car
}
}
@@kapitankrolick По поводу Вашего вопроса не могу пока точно ответить.
@@bukanaka спасибо) буду продолжать искать ответ)
@@kapitankrolick Минин обэясняет все так, что ничерта не понятно даже в тех темах, которые тебе уже известны и понятны. Смотри нормальных авторов и все будет понятно: ua-cam.com/video/PFmuCDHHpwk/v-deo.html&ab_channel=ProgrammingwithMosh
далее: callback, promise, async/await.
Кайф! Тяжело найти в инете такое понятное объяснение. Спасибо!
Ваш контент из русскоязычного один из лучших, что я видел/читал.
Благодарю)
Сделал 2 раза, один раз не понял в чем прикол и сделал через bind. Потом посмотрел как ты решил, понял, что смысл был в том, чтобы не использовать bind. На сл. день сел, написал
function bind (context, fn) {
return fn.apply(context)
}
оно работает, и я не понял зачем ещё какие-то аргументы передавать... В общем, было прикольно подумать, но задачка должна быть явно какой-то другой)
Спасибо. С 4-ого раза просмотра видео, мне всё же удалось, самому написать функцию bind работающую.
На канале есть подробный ролик про его создание)
Спасибо большое за объяснение!
Но всё же не совсем понятно, зачем в данном случае нужно замыкание. Можно ведь в рамках одной функции всё сделать:
function bind(context, fn) {
return fn.call(context)
}
Какой практический смысл здесь в замыкании?
там даже return не нужен
тогда ведь теряется смысл, который заложен в оригинальный bind: сначала указывается контекст, затем вызывается. Собственно, замыкание в этом случае и служит как раз для "отложенного" вызова.
Честно сказать я еще как (trainee), запутался из-за того что функция называется bind, и подумал что ты создаешь новую функцию для метода .bind и вызвав метод можно получится эту функцию, ну примерно как prototype, и только спустя час и долгих раздумий, я понял что это проссссто название функции где там так и было написано «свою функцию bind»
Лучше Имена не называть именами методов свойст и так далее для страховки
Очередное видео на данном канале, которое было для меня невероятно полезным :)
Плейлист "Сложный JavaScript простым языком" - лучшие материалы по JS из мной увиденных, в очередной раз хочу выразить благодарность автору!
9:33 Что касается задания с функцией bind, вот моё решение (в одну строчку):
const bind = (obj, funct) => funct.bind(obj);
Или же:
function bind(obj, funct) { return funct.bind(obj); }
P.S. Я не уверен на сто процентов, верное ли это решение (если оно в чём-то ошибочно, поправьте меня, кто знает лучше), но проверял с такими же объектами person, как и в примере, с функциями, которые принимают от 0 до 3 аргументов, и всё работает.
UPD: нет, не всё! Функция bind должна быть каррируемой, тоесть должна уметь принимать аргументы как в первых скобках, так и во вторых. Посмотрите видео, которое автор рекомендует в комментарии к данному комментарию, там он всё объясняет идеально понятно.
Глянь на канале подробный разбор bind 4 способа
Думаю что код написан правильно т.к. дело не в принимаемых аргументах, нет. Стрелочные ф-ции как и каррируемые могут создавать замыкание, они все же имеют доступ к содержимому родителя (по научному "лексическому окружению родителя"). Замыкание и каррирование - это разные вещи. Карррируемые ф-ции в отличии от стрелочных преобразуют ф-ции с множеством аргументов в последовательность ф-ций с одним аргументом. И спасибо за коммент, узнал что есть каррируемые ф-ции)👍
Кто-то пишет ,что сложно и не понятно😂 но по мне это самое крутое обьяснение замыкания которое я видел
Ты лучший. Наконец стал понятен смысл замыканий
Ты лучший фронтенд блогер. И я могу обосновать это. Во-первых: за такой короткий промежуток времени ты создал огромный канал с исчерпывающей информацией по фронтенд разработке. Во-вторых: любой человек с желанием может просто внимательно смотря твои видео по порядку и выполняя вместе с тобой задачи научиться всему за кратчайшие сроки. Все это благодаря структурированности и продуманности каждого плейлиста и видео. Я боюсь представить скольких усилий это все тебе стоило. В-третьих: все видео без лишней воды, и неуместных рофлов. В-четвертых: на этом канале я не увидел ни одного видео ради видео, каждое видео отличается от другого и раскрывает разные темы. В-пятых: четкая дикция, отлично выступаешь на камеру. Ты на верном пути братан, продолжай
Благодарю за такой отзыв, мне очень приятно)
О боги,я понял это спустя неделю попыток и тонны лит-ры и видео) Прикладные примеры - самое важное,за это отдельное спасибо!
@@ne4to777 Почему ты так уверен?)
@@ne4to777 Ну не в развернутой форме, очевидно (формат не подразумевает)
Но все же, базовое понимание видео дало
На мой взгляд стоило сделать немного иначе.
function bind(fn) {
return function(context) {
fn.apply(context)
}
}
const personData = bind(logPerson)
Получили функцию, возвращающую данные любого человека.
Лучший способ научить - самый простой!
Спасибо, переплюнул 90% инфы на эту темую
я что-то не вкурил про аргументы. они ведь не передаются. откуда они появляются ?
а с учетом первичного задания, все вообще сводится до fn.apply(context)()
Там не аргументы появились, а поля объекта из контекста. Я так понял параметры функция принимает, потому что спроектирована с запасом на разные ситуации.
Они появляются от rest params
По последней задачки думаю нужен апдейт:
Функция bind в вашем примере создает "обертку" вокруг функции fn, которая при вызове устанавливает this в переданный контекст context. Это позволяет вам вызывать функцию fn так, как если бы она была методом объекта context.
Давайте разберемся, как это работает, шаг за шагом:
1. bind принимает два аргумента: context и fn.
2. bind возвращает новую функцию, которая при вызове будет применять функцию fn к контексту context.
3. Когда возвращенная функция вызывается, она использует ...args для сбора всех переданных аргументов в массив args.
4. fn.apply(context, [args]) вызывается внутри этой функции. Метод apply используется для вызова функции fn с конкретным значением this (в данном случае context) и массивом аргументов args.
В вашем конкретном случае использование ...args и [args] вокруг args не имеет смысла, поскольку logPerson не принимает никаких аргументов, и использование apply с массивом аргументов в этом случае избыточно. Это может быть полезно, если бы функция logPerson принимала дополнительные параметры.
Тем не менее, чтобы функция bind работала корректно с функцией logPerson, которая не принимает аргументы, вам нужно вызвать fn.apply(context) без второго параметра или использовать пустой массив для аргументов:
function bind(context, fn){
return function(){ // здесь args не нужны, так как logPerson их не принимает
return fn.apply(context); // вызываем fn с контекстом context и без аргументов
}
}
bind(person1, logPerson)(); // Person: Misha, 22, Frontend
bind(person2, logPerson)(); // Person: Lena, 18, SMM
Использование ...args и [args] имело бы смысл, если бы вы хотели, чтобы функция bind могла принимать и передавать любое количество аргументов в функцию fn, но в вашем текущем примере это не требуется.
я наконец-то понял, что такое замыкание , спасибо тебе огромное 🚀
Вот вам детки задачка по математике из 1 класса школьной программы. Поняли? Отлично! Вот пример из 2 класса школьной программы. А вот из 3 класса. Усвоили? Замечательно, молодцы!! А теперь поставьте видео на паузу и самостоятельно решите задачку которую дают на олимпиадах по математике для 11 класса)))))) Не можете? Сейчас вместе разберём... И на самом интересном месте вылетает реклама закрывающая треть экрана))))))))))) Владлен, моё к вам уважение! Ваши уроки хороши, но понять их порой крайне не просто.
но в целом очень нравится, у Вас реально талант объяснять простым языком. Этого сейчас очень мало на ютубе, одно бла бла бла, я понимаю что русский язык позволяет заниматься разглагольствованием, но хочется максимум понятной информации за минимальное время, у Вас пока по тем видео которым я смотрел все так, т.е. можно джуниоров натаскивать по Вашим видео :) все всё поймут. Спасибо еще раз.
Благодарю за отзыв
Дело не в языке, а в понимании и умении
Те, кто льют воду сами плохо разбираются
Премию оскар за лучшее русскоязычное объяснение javascripta )
Вообще лучшее объяснение!
Комментарий из восьми слов для поддержки этого видео.
Не уверен, что этимология верна, но подача удобная.
Кастомный bind без использования apply/call:
function bind(context, f){
const obj = {...context, f}
obj.f()
}
Спасибо! Наконец Я понял замыкание полностью 😂
Действительно простым языком. Спасибо за материал, помогли разобраться!
Большое спасибо Автору за: показал зачем оно в практическом смысле надо. А то остальные только счетчик показывают и всё
я ша изучаю как работает движок js, и для меня оно чуть не так все. думаю Владилен поймет о чем я, более сложно. у меня там области видимости, ячейка памяти, чистильщик работает, в моем понимании замыкания. к чему же эту хрень то несу? да к тому, что Владилен в отличии от всех остальных, рассказал это максимально приближенно к тому, как оно работает на уровне компилятора. я аж прям залип на теме углубленного изучения js. как сел читать, сразу глобальная область видимости, потом правый и левый поиск, потом дошел до замыканий, и все второй день не могу оторваться от этой темы. ша this изучаю, как предмет динамической области видимости (просто в js лексическая)... и зашел опять в ютуб, посмотреть что да как на более легком уровне. ну и как не крути, у Владилена максимально все приближено к сложным темам, но рассказано простым языком. видно что тоже видать в свое время как и я сейчас, упарывался в глубь этого всего.))) спасибо!
Спасибо за урок!
круто все. Было здорово посмотреть твой урок по созданию JAVASCRIPT плагина.
Огромное спасибо! Шедевральное обьяснение с примерами. Как минимум, можно будет обьяснить на собеседовании принцип работы или написать самому, а не пытатьсчя заучивать непонятные словешки)))
Владлен, у тебя ахрененный канал. Побольше бы таких))
Благодарю)
Спасибо большое за урок. Только есть вопрос про последнее действие.
Понятно что метод apply() должен обязательно иметь два параметра, но что имеется ввиду под массивом ...args ? не понял зачем нужно передавать внутри второй функции ещё какие-то параметры, если функция bind требует только обьект для контекста (person) и саму функцию вывода (logPerson) информации в консоли ?
объясняешь великолепно
Вариант без apply/call:
ниже :)
const bind = (ctx, fn) => (...args) => {
const s = Symbol('fn');
const o = {...ctx, [s]: fn};
return o[s](...args);
};
Такая реализация требует пояснений ;)
Сократи еще больше. Bind замени на b, args на a. ну ты понял в общем. На собесе сразу на сеньора возьмут. Сразу будет понятно что человек умный, умеет коротко писать, стрелочки знает
@@АлександрВельможко-ю4з ахахаххахахаахаах
спасибище, реально все четко и понятно!
Лаконично!!👍👍👍 без воды и с реальными примерами
Хорошие примеры замыкания в видео. Переписал один для Python.
# пример замыкания функции
def url_generator(domain):
def function_url(url):
return f"{url}.{domain}"
return function_url
com_url = url_generator("com")
ru_url = url_generator("ru")
print(com_url("google"))
print(com_url("netflix"))
print(ru_url("google"))
print(ru_url("netflix"))
Прежде изучал Питон и почему там всё было достаточно понятно: this, замыкания, декораторы, ООП. Потом забросил его и сейчас изучаю JS, и вроде те-же самые понятия, но доходит с трудом.
Чувак, огромная благодарность!) Великолепно объясняешь!
Замечательное объяснение. Спасибо!
Шикарная информация!
Владилен, пример в конце прекрасный, как и все Ваши видео, но тут, конечно, в конце задача с подвохом. Решить данную задачу таким способом, как это сделали Вы изначально тяжело, именно по причине того, что по условию изначально мы должны получить значения без вызова функции. И вроде работает без args.
Владилен, снимаю шляпу!) Прекрасно объясняешь теперь. Не то, что в курсах платных (если честно, не понимаю почему), может просто опыт преподавания растёт))) Так держать! То же и про .bind и .call.
Опыт да. Владлен норм так начал рассказывать. И по делу и голос приятен.
Хз по моему платные курсы у него тоже отличные
Интересно, что при проверке решения у задачи меняются условия)) Задачки для самостоятельного решения - это хорошо, но данное задание вообще неоднозначное.
решил, как и многие ниже:
function bind (person, callback) {
callback.call(person)
}
В этом плейлисте два первых видео были просто великолепны, все чётко, ясно и понятно, но здесь что то пошло не так - тема замыкания не раскрыта, создание функции bind тоже, скорее ещё больше запутался... пошёл разбираться
На канале есть подробный ролик про bind
Как вариант своего apply, но с добавлением свойства в объект. Возможно, символом можно нивелировать влияние:
function bind(context, func) {
return function () {
context['f'] = func;
return context.f();
}
}
function logPerson() {
console.log(`Person: ${this.name}, ${this.age}, ${this.job}`)
}
const person1 = { name: 'Михаил', age: 22, job: 'Frontend' }
const person2 = { name: 'Елена', age: 19, job: 'SMM' }
bind(person2, logPerson)()
Спасибо за хорошее объяснение.)
Отличный контенет. Спасибо
Большое спасибо, все понятно, но пришлось пройти дебагером, чтобы понять для чего передавать args!
Если посмотреть закоментировааный код, который должен был отработать, то в нем предпологалось вызвать bind уже как функцию. А реализация оказалось иной в итоге. Ну раз был добавлен оператор spread, то надо было показать для чего это сделано, т.к. в контексте закоментированного задания это не требовалось делать. Итог, чтобы работало, как было в постановке задаче , достаточно было написать фунцию: function bind(context, fn) {
return fn.call(context);
}. Чтобы использовать args, вероятно надо модифицировать функцию logPerson(data), передав в нее дополнительный объект. Или как автор хотел использовать пердаваемые аргументы не понятно.
Спасибо. Именно у вас понял.
На самом деле, Вы большой молодец, Владилен)) Спасибо!
Спасибо за урок! Не понял только в конце в функции bind в возвращаемую функцию мы передаем args и их потом в метод apply. Как и где на практике мы можем передать эти аргументы в возвращаемую функцию? Сейчас функция bind работает и без этих аргументов
плюсую, до меня вообще долго доходило что в примере мы это место не используем
Тоже не понял - для чего в примере ...args ?
Отличные видео! Прямо сморишь и рад что нашел :) Приятный тон и тембр, довольно легко все воспринимается. Без лишнего, только основные моменты. Единственное что хотелось бы еще услышать в контексте плейлиста, так это о лексическом окружении, контекстах, скоупах, ивент лупе и подобных подкапотных штуках. С умением объяснять простыми словами поможет сильно начинающим в понимании JS. Лайки/звоночки нажал. Первый канал который так зашел что даже сморишь то что уже знаешь)))
Спасибо за уроки, отличное качество.
Благодарю за отзыв)
Ознакомься с другими роликами на канале
@@VladilenMinin Я знаком, спасибо и буду знакомиться дальше). Удачи в делах!
Спасибо тебе, Ленин, ты крут!
Отличный урок!
Спасибо, это лучшее объяснение.
я вот просто, благодарен за твои уроки!!!!!!!!!!!
Альтернативное решение:
function bind(context, func) {
context[func] = func;
context[func]()
}
function bind(obj, func) {
const context = { ...obj, func } // closure
return function() { context.func(); } // returning a function
}
Единственно верный вариант ответа. Ибо call и apply это по сути тот же bind.
Лучшее объяснение замыканий в JavaScript, что я слышал
Довольно простая тема, если по человечески её объснить) Спасибо, наконец-то понял на 100%
@@ne4to777 это когда функция получила внешнюю переменную и забыла про внешнюю)
@@ne4to777 ага. работает с ней как с копией)
офигенный урок
Сделал так (писал на typescript):
Function.prototype.myBind = function (context: object, ...args: any[]) {
const newContext = { ...context, bindedFunction: this }
return function () {
newContext.bindedFunction(...args)
}
}
Все супер. Показал кучу примеров, но всё таки, что такое замыкания и как они работают ты не объяснил. Замыкания это не функция внутри другой функции!!! Цитирую К. Симпсона: "Замыканием называется способность функции запоминать свою лексическую область видимости и обращаться к ней, даже когда функция вызывается за пределами своей лексической области видимости". Я думаю это вызовет у новичков ложное чувство, что они узнали, что такое замыкания, что и видно из комментариев. Если хотите на самом деле узнать про замыкания, то очень хорошо это разжевывается в книге "Вы не знаете JS"
Повторю наверное в 10 раз, что этот плейлист не учебник, а способ дать людям понять «сложные» концепты. Чтобы у них было представление об этом и чтобы они научились этим пользоваться
Чувак у тебя один из самых годных контентов на русском языке. Мало кто может так преподать материал. Остальные в основном рассказывают тему, как ученик рассказывает выученный урок перед доской. Но на счет конкретно темы замыканий я не согласен. Важно понимать подробно как они работают. И это становится простым, когда человек проясняет для себя области видимости. Не смотря на всю простоту, даже опытные разработчики до конца не понимают, что это вообще такое. А новички просмотрев это видео придут в заблуждение и наверняка провалят собеседование по этой теме. Все кто написал, что наконец-то понял замыкание, попробуйте объяснить их самостоятельно. Я думаю, что вы убедитесь, что ничего так и не поняли.
Согласен с Радиславом Ялиловым! По комментариям видно, что многие засомневались! Аrgs реально сбил с панталыку. Да и не понятно. в чем тут замыкание то? Ну передали аргументы в функцию, а замыкание при чем? Я не критикую, я так понял и сказал. Лучше говорить чем молчать! ))) Сразу скажу, что я подписан на канал автора и звонок нажат )
@@englishlanguage1281 Ох запишу ка я отдельное подробное видео про это
Если честно задание было сложное. Возможно потому что я начинающий. Было сложно догадаться что нужно использовать создание нового массива ещё и с помощью оператора spread, хотя о нём я знал. Сложно понять почему он возвращается как аргумент в замыкающую функцию, также сложно понять почему аргументы самой функции bind сначала контекст а потом сама функция внутри bind. Вообщем если можно пожалуйста подробнее про это задание.
Всё ясно и понятно. Спасибо.
Привет, отлично!
Спасибо за видео, вот мой вариант ответа:
function bind(x) {
return function () {
this.name = x.name;
this.age = x.age;
this.job = x.job;
return logPerson()
}
}
bind(person1, logPerson)();
на ум пришло пока это, не особо знаком с apply
Такое же замутил)
Разобравшись что к чему, сделал (написал) так:
function bind(context, conclution) { ---> переменная context у нас привязана к person, а conclution к логу ф-ции logOerson т.к. в коде вывода bind(...) у нас указан вывод ф-ций logPerson и person1/person2, что дает нам понять привязку наших ДВУХ переменных в ф-ции bind к этим ДВУМ переменным в вызове bind. Непойму только зачем нам spread оператор, если без него все работает точно так же как и с ним (мы ведь в логе logPerson уже указываем как все должно выводится в консоль) Вопрос: это все называется замыканием из-за того, что мы вызываем ф-цию bind с указанной логикой к двум ф-циям глобальной видимости logPerson и person1/person2 повторно? Ока что это не особо понял, но за объяснение спасибо!
return function(){
conclution.apply(context)
}
}
function logPerson() {
console.log(`Person: ${this.name}, ${this.age}, ${this.work}`);
}
const person1 = {name:'Mihail', age: 22, work: 'Fronend'}
const person2 = {name:'Memoza', age: 19, work: 'SMM'}
bind(person1, logPerson)()
bind(person2, logPerson)()
Спасибо за видео!