Параметры по умолчанию | 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 или телеграмм чат, а также подписывайтесь на наши новости

Вопросы:​

Если параметрам функции⚙️ не передано значение, какое значение они принимают по умолчанию?

  1. null
  2. undefined
  3. NaN

Параметры по умолчанию «отлавливают» ложные значения?

  1. true
  2. false

Можно ли в параметрах по умолчанию использовать значения параметров расположенных левее в списке?

  1. true
  2. false

Для того чтобы понять, на сколько вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в нашем телеграм боте.

Ссылки:​

  1. MDN web docs

Contributors ✨​

Thanks goes to these wonderful people (emoji key):


Philipp Dvinyaninov
📖

Dmitriy Vasilev
💵

Resoner2005
🐛 🎨 🖋

Navernoss
🖋 🐛 🎨

JavaScript | setTimeout() | Как передать параметры в функцию-обработчик? — efim360.ru

Пример

Мы будем отложенно выводить в консоль браузера сумму чисел. То есть мы планируем передавать в функцию какие-нибудь числа, а потом дожидаться их сложения.

Напишем две функции:

  1. sum — складывает числа
  2. sleep2sec — запускает функцию sum, через 2 секунды

 

Функция sum()

function sum (x, y){
   console.log(`Сумма чисел: ${x + y}`)
}
Функция sum() — JavaScript

Эта функция выводит строку в консоль браузера.

В этой строке есть статичная часть «Сумма чисел: «, которая не изменяется. Также есть динамичная часть «${x + y}«, которая отображает сумму двух чисел (или результат конкатенации строк) — эта часть всегда высчитывается в момент вызова работы функции.

Эта функция работает с двумя аргументами, поэтому в неё нужно передавать два параметра — два числа для сложения. Под «x» будет первое число, а под «y» — второе.

Мы хотим понять, каким образом можно передавать эти параметры (

x, y) для вызова функции sleep2sec. То есть нам нужно сделать так, чтобы сначала передать два числа в функцию sleep2sec, а потом эти наши два числа каким-то образом пробросились внутрь функции setTimeout., а после неё пробросились во вложенную функцию sum.

 

Функция sleep2sec()

function sleep2sec (a, b){
   console. log("Отложенный вызов начался")
   setTimeout(sum, 2000, a, b)
}

Передача параметров в функцию setTimeout осуществляется с третьего аргумента. То есть первым аргументом мы передаём функцию-обработчик, вторым аргументом — задержку в миллисекундах и начиная с третьего идут параметры через запятую.

В нашем случае:

  • Первый аргумент функции setTimeout — это функция-обработчик sum
  • Второй аргумент функции setTimeout — это число, которое обозначает миллисекунды — это время задержки (отложенного вызова sum)
  • Третий аргумент функции setTimeout — это первое передаваемое число в sum
  • Четвёртый аргумент функции setTimeout — это второе передаваемое число в sum
Функция sleep2sec — расписаны аргументы для setTimeout — JavaScript

 

Вызов функции 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 , на который указывалось, не изменилось. Этот это потому, что мы не указали

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 для ссылки на контекст, в котором вы ее изначально написали, вы можете обнаружить, что вызов его в качестве обратного вызова из другой функции изменяет то, на что ссылается этот — обычно возвращаясь к глобальному объекту/окну.