Параметры по умолчанию | JavaScript Camp
Параметры по умолчанию позволяют задавать параметрам функции⚙️ значения по умолчанию в случае, если функция⚙️ вызвана без аргументов, или если параметру явным образом передано значение undefined.
В JavaScript параметры функции⚙️, которым при ее вызове не передаются значения, принимают по умолчанию значение undefined. Однако в некоторых случаях может быть полезно задать иное значение по умолчанию. Именно для таких случаев предназначены параметры по умолчанию.
Синтаксис
function learnJavaScript() { const multiply = (a, b = 1) => { //Значение по умолчанию у b равно 1 return a * b } //Если b будет undefined, то ему присвоится значение по умолчанию return multiply(5, 2) // удалите запятую, второй аргумент и получите 5 * 1 }
Loading.
..
Видео
Передача других «ложных» значений
Если формальному параметру при вызове передано любое значение, отличное от undefined, в том числе одно из «ложных» значений, таких как false ❎ , 0, "", '',null, NaN, то в этом случае значение по умолчанию присвоено параметру не будет. В этом случае нужно самому прописывать 🖊️ код который будет отлавливать эти «ложные значения».
Примеры
В параметрах по умолчанию можно использовать значения предыдущих (расположеннных левее в списке) параметров:
function learnJavaScript() { const greet = (name, greeting, message = greeting + ‘ ‘ + name) => { return [name, greeting, message] } return greet(‘David ‘, ‘Hi ‘) }
Loading.
..
Пример функции с параметрами по умолчанию и без них 👇 :
function learnJavaScript() { const withDefaults = (a = 1, b = 3, c = 2) => { //Функия с параметрами по умолчанию return [a, b, c] } const withoutDefaults = (a, b, c) => { //Функция без параметров по умолчанию if (a == undefined) { a = 1 } if (b == undefined) { b = 3 } if (c == undefined) { c = 2 } return [a, b, c] } return withDefaults() }
Loading.
Результат будет тот же, но без параметров по умолчанию код📟 может стать заметно больше.
React Native
Большинство компонентов можно настроить при их создании с различными параметрами. Эти параметры создания называются — props. Обратите внимание на то, что в третий компонент HelloWorld мы не передаем name поэтому рапечатывается имя Вася
Использование name в качестве props позволяет нам настроить компонент приветствия, чтобы мы могли повторно использовать этот компонент для каждого из наших приветствий. В этом примере также используется компонент HelloWorld в JSX. Способность делать это — вот что делает React таким крутым.
Проблемы?
Пишите в Discord или телеграмм чат, а также подписывайтесь на наши новости
Вопросы:
Если параметрам функции⚙️ не передано значение, какое значение они принимают по умолчанию?
nullundefinedNaN
Параметры по умолчанию «отлавливают» ложные значения?
truefalse
Можно ли в параметрах по умолчанию использовать значения параметров расположенных левее в списке?
truefalse
Для того чтобы понять, на сколько вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в нашем телеграм боте.
Ссылки:
- MDN web docs
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Philipp Dvinyaninov 📖 | Dmitriy Vasilev 💵 | Resoner2005 🐛 🎨 🖋 | Navernoss 🖋 🐛 🎨 |
JavaScript | setTimeout() | Как передать параметры в функцию-обработчик? — efim360.ru
Пример
Мы будем отложенно выводить в консоль браузера сумму чисел. То есть мы планируем передавать в функцию какие-нибудь числа, а потом дожидаться их сложения.
Напишем две функции:
- sum — складывает числа
- sleep2sec — запускает функцию sum, через 2 секунды
Функция sum()
function sum (x, y){
console.log(`Сумма чисел: ${x + y}`)
}Функция sum() — JavaScriptЭта функция выводит строку в консоль браузера.
Эта функция работает с двумя аргументами, поэтому в неё нужно передавать два параметра — два числа для сложения. Под «x» будет первое число, а под «y» — второе.
Мы хотим понять, каким образом можно передавать эти параметры (
Функция sleep2sec()
function sleep2sec (a, b){
console.
log("Отложенный вызов начался")
setTimeout(sum, 2000, a, b)
}Передача параметров в функцию setTimeout осуществляется с третьего аргумента. То есть первым аргументом мы передаём функцию-обработчик, вторым аргументом — задержку в миллисекундах и начиная с третьего идут параметры через запятую.
В нашем случае:
- Первый аргумент функции setTimeout — это функция-обработчик sum
- Второй аргумент функции setTimeout — это число, которое обозначает миллисекунды — это время задержки (отложенного вызова sum)
- Третий аргумент функции setTimeout — это первое передаваемое число в sum
- Четвёртый аргумент функции setTimeout — это второе передаваемое число в sum
Вызов функции sleep2sec() с параметрами
sleep2sec(1,2)Вызов функции sleep2sec с параметрами 1, 2 — JavaScript
sleep2sec(473,593)Вызов функции sleep2sec с параметрами 473, 593 — JavaScript
После вызова функции sleep2sec проходит 2 секунды и в консоль выпадает сумма чисел.
Короткая справка по setTimeout()
handle = self . setTimeout( handler [, timeout [, arguments... ] ] )
Планирует тайм-аут для запуска обработчика после тайм-аута в миллисекундах. Любые аргументы передаются непосредственно обработчику.
handle = self . setTimeout( code [, timeout ] )
Планирует тайм-аут для компиляции и запуска кода после тайм-аута в миллисекундах.
Метод setTimeout() должен возвращать значение, возвращаемое этапами инициализации таймера, передавая им аргументы метода, объект, на котором реализован метод, для которого выполняется алгоритм (объект Window или WorkerGlobalScope) в качестве «контекста метода«, и флаг «повторения» установлен в значение false.
Информационные ссылки
JavaScript | setTimeout()
Стандарт HTML (whatwg) — Таймеры — https://html.
spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
HTML | Таймеры
Стандарт HTML (whatwg) — Миксин WindowOrWorkerGlobalScope — https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope-mixin
Стандарт HTML (whatwg) — Метод setTimeout() — https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
Стандарт ECMAScript — Функции — https://tc39.es/ecma262/#sec-function-objects
Параметры функции передачи JavaScript по значению
Почему это не работает?
функция getLogger(аргумент) {
регистратор функций () {
console.log(аргумент)
}
регистратор возврата
}
пусть фрукты = 'малина'
const logFruit = getLogger(фрукты)
logFruit() // "малина"
фрукты = «персик»
logFruit() // "малина" Подождите!? Почему это не "персик"?
Итак, чтобы обсудить, что здесь происходит, я создаю переменную с именем фрукты и присвоение их строке 'малина' , то я передаю фруктов в
функция, которая создает и возвращает функцию с именем logger , которая должна регистрировать фруктов при вызове.
console.log .
из "малина" как и ожидалось. Но затем я переназначаю фрукты на «персик» и снова вызываю регистратор . Но
вместо получения console.log нового значения fruit я получаю старое
значение фрукты !
Я могу обойти это, снова вызвав getLogger , чтобы получить новый регистратор:
const logFruit2 = getLogger(fruit) logFruit2() // "персик", какое облегчение...
Но почему я не могу просто изменить значение переменной и заставить регистратор записать последнее значение?
Ответ заключается в том, что в JavaScript при вызове функции с аргументы, аргументы, которые вы передаете, передаются по значению, а не по ссылке. Позвольте мне кратко описать, что здесь происходит:
функция getLogger(аргумент) {
регистратор функций () {
console.log(аргумент)
}
регистратор возврата
}
// примечание, это тоже можно написать так
// и это не имело бы никакого значения:
// const getLogger = arg => () => console.
log(arg)
// Я просто решил сделать это более подробным, чтобы не усложнять
При вызове getLogger создается функция logger . Это совершенно новый
функция. Когда создается новая функция, она ищет все
переменные, к которым он имеет доступ, и «закрывает» их, чтобы сформировать то, что называется
«закрытие». Это означает, что пока это регистратор функция существует, она будет
иметь доступ к переменным в родительской функции и других модулях
переменные.
Итак, к каким переменным имеет доступ регистратор при его создании? Глядя на
пример снова, он будет иметь доступ к fruit , getLogger , arg и logger (сам). Прочтите этот список еще раз, потому что это важно для того, чтобы код работал правильно.
так оно и есть. Вы что-то заметили? Оба и arg перечислены, даже
хотя они имеют точно такое же значение!
То, что двум переменным присвоено одно и то же значение, не означает, что они являются
та же переменная.
Вот упрощенный пример этой концепции:
пусть a = 1 пусть б = а console.log(а, б) // 1, 1 а = 2 console.log(a, b) // 2, 1 ‼️
Обратите внимание, что даже если мы сделали b указанием на значение переменной a , мы
возможность изменить переменную на и значение b , на который указывалось, не изменилось. Этот
это потому, что мы не указали на a как таковые. Мы указали b на значение a указывал в то время!
Мне нравится думать о переменных как о маленьких стрелках, указывающих на места в таблице.
память компьютера. Итак, когда мы говорим let a = 1 , мы говорим: «Эй, JavaScript!
engine, я хочу, чтобы вы создали место в памяти со значением 1 , а затем
создайте стрелку (переменную) с именем a , указывающее на это место в памяти».
Затем, когда мы говорим: let b = a , мы говорим: «Эй, движок JavaScript, я хочу, чтобы ты
чтобы создать стрелку (переменную) с именем b , которая указывает на то же место, что и a указывает на в данный момент.
»
Таким же образом, когда вы вызываете функцию, механизм JavaScript создает новую
переменная для аргументов функции. В нашем случае мы вызвали getLogger(fruit) .
и движок JavaScript в основном сделал это:
пусть аргумент = фрукты
Итак, когда мы позже сделаем fruit = 'peach' , это не повлияет на arg , потому что
это совершенно разные переменные.
Думаете ли вы об этом как об ограничении или как о функции, факт в том, что это как это работает. Если вы хотите поддерживать актуальность двух переменных друг с другом, есть способ сделать это! Ну типа. Идея такова: вместо изменения там, где указывают стрелки (переменные), вы можете изменить то, на что они указывают! За пример:
пусть = {текущий: 1}
пусть б = а
console.log(a.current, b.current) // 1, 1
ток = 2
console.log(a.current, b.current) // 2, 2 🎉
В этом случае мы не переназначаем a, а меняем значение, которое a равно
указывая на.
И поскольку b указывает на одно и то же, они оба
получить обновление.
Итак, давайте применим это решение к нашей проблеме с регистратором :
function getLatestLogger(argRef) {
регистратор функций () {
console.log(argRef.current)
}
регистратор возврата
}
const fruitRef = {текущий: 'малина'}
const lastLogger = getLatestLogger (fruitRef)
lastLogger() // "малина"
fruitRef.current = 'персик'
lastLogger() // "персик" 🎉
Суффикс Ref является сокращением от «ссылка», что означает, что значение
переменная указывает на, просто используется для ссылки на другое значение (которое в нашем случае
является текущим свойством объекта).
С этим, естественно, приходится идти на компромиссы, но я рад, что JavaScript
спецификация требует, чтобы аргументы функции передавались по значению, а не
ссылка. И обходной путь не доставляет особых хлопот, когда вам это нужно.
(что довольно редко, потому что изменчивость делает программы более трудными для понимания
обычно).
Надеюсь, это поможет! Удачи!
Передача функций в качестве аргументов в JavaScript — советы и подводные камни | by Ciaran Morinan
Функции в JavaScript являются «первоклассными», что означает, что они обрабатываются как любая другая переменная, включая передачу или возврат из других функций.
Когда они передаются в качестве аргумента другой функции, они называются «обратными вызовами» — их вызывают, когда другая функция готова для них.
Общие примеры обратных вызовов включают функции, предоставляемые:
-
forEachиликартавызывается для каждого элемента в коллекции поселился
Это может не всегда идти по плану — этот блог затрагивает несколько причин, почему.
Вы можете писать функции обратного вызова полностью внутри функции, которая в них нуждается, но для простоты чтения и отладки часто бывает полезно объявить или назначить их в другом месте и ссылаться на них по имени функции или переменной.
Первое, на что следует обратить внимание, это то, что вы на самом деле ссылаетесь на них по имени — , а не , вызывая их. В этом разница между записью myFunction (возвращает функцию) и myFunction() (выполняет ее).
Если вы предоставляете функцию в качестве обратного вызова для другой функции, это задача этой другой функции выполнить ее, когда она будет готова, а не ваша, т. е.
Здесь setTimeout ищет первый аргумент для предоставления0182 вещь, которую нужно сделать, когда вы будете готовы ’. Если мы вызываем sayBoo() , а не ссылаемся на него, мы фактически предоставляем setTimeout то, что возвращает sayBoo() — в данном случае ничего, что он может выполнить. Если бы sayBoo() вернул функцию, то эта функция была бы доступна для setTimeout .
Могут быть случаи, когда вы хотите мгновенно вызвать функцию и заставить ее возвращать другую функцию для использования в качестве обратного вызова, но если вы этого не делаете и ваши обратные вызовы ведут себя не так, как ожидалось, проверьте что вы только ссылаетесь на имя функции (или имя переменной, в которой вы сохранили функцию), а не вызываете ее на месте!
Нам нужно по-другому думать о том, как мы передаем аргументы функциям обратного вызова.
Мы не можем указать имя функции с аргументами прямо в скобках — это приведет к тому, что она будет выполнена немедленно, а не останется в качестве обратного вызова, когда окружающая функция будет готова для него.
Например, если мы хотим создать обратный отсчет, который вызывает сам себя:
… мы не можем предоставить обратный отсчет(--n) таким образом, потому что он вызывается, как только оценивается строка 4, а не звонит setTimeout , когда будет готово. Добавление скобок () (с аргументами внутри них или без них) означает, что мы выполняем функцию на месте, а не передаем ее в качестве аргумента.
setTimeout и setInterval на самом деле имеют свой собственный способ справиться с этим — вы можете предоставить третий аргумент (и столько, сколько хотите) любому из них, который будет передан функции обратного вызова [не поддерживается IE9 ].
Или вы можете предоставить короткую анонимную функцию в качестве обратного вызова, которая затем сама выполняет именованную функцию при вызове.
Оба видели здесь:
Для таких функций, как forEach , map и then , у которых есть готовые аргументы для передачи в их функции обратного вызова (например, текущее значение в перебираемой коллекции или значение разрешенного промиса ), вы можете воспользоваться возможностью JavaScript использовать неявное или «бесточечное» программирование.
Это включает указание функции в качестве обратного вызова без указания аргументов, которые будут переданы ей — вызывающая функция будет передавать любые доступные значения в качестве аргументов, чтобы обратный вызов мог обрабатывать их, как может.
В приведенном выше примере у нас есть функция saySquared , которая принимает один аргумент. forEach на самом деле может предложить три — текущее значение, текущий индекс и исходную коллекцию — но функции JavaScript не жалуются, если вы предоставляете им больше аргументов, чем им нужно, и так до тех пор, пока вы знаете порядок в какие аргументы будут предоставлены, вы можете эффективно использовать стиль.
Если вы не уверены, какие аргументы будут переданы функцией и в каком порядке, обратитесь к документации. В качестве наглядного пособия также можно пройти console.log в качестве обратного вызова функции, использующей молчаливый стиль, опуская любые другие инструкции — он с радостью примет любое количество предоставленных аргументов и распечатает их для вас.
Не всегда уместно использовать молчаливое программирование — в некоторых случаях читателю (будь то кому-то другому или вам из будущего) будет сложнее понять, что происходит, особенно если он не знаком с аргументами функция предоставляет обратный вызов, или если ваш обратный вызов использует только некоторые из доступных значений.
Третье, что следует иметь в виду, это то, как использование функций в качестве обратных вызовов изменяет контекст, в котором они вызываются. Если ваша функция использует ключевое слово this для ссылки на контекст, в котором вы ее изначально написали, вы можете обнаружить, что вызов его в качестве обратного вызова из другой функции изменяет то, на что ссылается этот — обычно возвращаясь к глобальному объекту/окну.

log("Отложенный вызов начался")
setTimeout(sum, 2000, a, b)
}
log(arg)
// Я просто решил сделать это более подробным, чтобы не усложнять