От автора: в ECMAScript 2015, в JavaScript были введены параметры функций по умолчанию. Это позволяет разработчикам инициализировать функцию со значениями по умолчанию, если аргументы не передаются в вызов функции. Таким образом, инициализация параметров функции сделает функции более легкими для чтения и менее подверженными ошибкам, а также обеспечит для функций поведение по умолчанию. Это поможет вам избежать ошибок, связанных с передачей аргументов undefined и деструктурированием несуществующих объектов.
В этой статье мы рассмотрим разницу между параметрами и аргументами, узнаем, как использовать в функциях параметры по умолчанию, поймем альтернативные способы поддержки параметров по умолчанию и узнаем, какие типы значений и выражений можно использовать в качестве параметров по умолчанию. Вы также познакомитесь с примерами, демонстрирующими работу параметров по умолчанию в JavaScript.
Аргументы и параметры
Прежде чем объяснять параметры функции по умолчанию, важно знать, чем могут быть параметры по умолчанию. Поэтому мы сначала рассмотрим разницу между аргументами и параметрами в функции. В следующем блоке кода мы создаем функцию, которая возвращает куб заданного числа, определяемого как x:
1 2 3 4 |
// Define a function to cube a number function cube(x) { return x * x * x } |
Переменная x в этом примере является параметром — именованной переменной, передаваемой в функцию. Параметр всегда должен содержаться в переменной и никогда не должен иметь прямого значения. Теперь взгляните на следующий блок кода, который вызывает функцию cube, которую мы только что создали:
1 2 |
// Invoke cube function cube(10) |
Это даст следующий вывод: 1000.
В данном случае 10 — это аргумент, значение, передаваемое функции при ее вызове. Часто значение будет также содержаться в переменной, например, в следующем примере:
1 2 3 4 5 |
// Assign a number to a variable const number = 10 // Invoke cube function cube(number) |
Это даст тот же результат: 1000.
Если вы не передадите аргумент функции, которая ожидает его, функция будет неявно использовать в качестве значения undefined:
1 2 |
// Invoke the cube function without passing an argument cube() |
Это вернет: NaN.
В данном случае cube() пытается вычислить значение undefined * undefined * undefined, результат чего NaN, или «не число». Такое автоматическое поведение иногда может быть проблемой. В некоторых случаях вы можете захотеть, чтобы параметр имел значение, даже если в функцию не был передан аргумент. Вот где окажутся полезными параметры по умолчанию — тема, которую мы рассмотрим в следующем разделе.
Синтаксис параметров по умолчанию
С добавлением в ES2015 параметров по умолчанию теперь вы можете назначить значение по умолчанию для любого параметра, который будет использоваться функцией вместо вызова undefined без аргумента. Мы сначала расскажем, как это сделать вручную, а затем рассмотрим настройку параметров по умолчанию.
Без параметров по умолчанию вам придется явно проверять значения undefined, чтобы установить значения по умолчанию, как показано в этом примере:
1 2 3 4 5 6 7 8 9 10 |
// Check for undefined manually function cube(x) { if (typeof x === 'undefined') { x = 5 } return x * x * x } cube() |
При этом используется условный оператор для проверки, было ли значение автоматически предоставлено как undefined, а затем устанавливается значение x, как 5. Это приведет к следующему выводу: 125.
Напротив, использование параметров по умолчанию позволяет достичь той же цели с помощью гораздо меньшего количества кода. Вы можете установить значение по умолчанию для параметра cube, присваивая его с помощью оператора равенства (=), как показано ниже:
1 2 3 4 |
// Define a cube function with a default value function cube(x = 5) { return x * x * x } |
Теперь, когда функция cube вызывается без аргумента, для x назначается 5, благодаря чему мы получаем результат вычислений, вместо NaN:
1 2 |
// Invoke cube function without an argument cube() |
Это приведет к следующему выводу: 125.
Когда будет передан аргумент, он будет работать так, как задумано, и значение по умолчанию будет игнорироваться:
1 2 |
// Invoke cube function with an argument cube(2) |
Это приведет к следующему выводу: 8.
Однако следует отметить одно важное предостережение: значение параметра по умолчанию также переопределяет явное undefined, переданное в качестве аргумента функции, как показано ниже:
1 2 |
// Invoke cube function with undefined cube(undefined) |
Это даст расчет с х, равным 5: 125.
В этом случае были вычислены значения параметров по умолчанию, и явное значение undefined не переопределило их. Теперь, когда у вас есть представление об основном синтаксисе параметров по умолчанию, в следующем разделе будет показано, как параметры по умолчанию работают с различными типами данных.
Типы данных параметров по умолчанию
Любое примитивное значение или объект может использоваться в качестве значения параметра по умолчанию. В этом разделе вы увидите, как эта гибкость увеличивает возможности использования параметров по умолчанию.
Сначала установите параметры, используя число, строку, логическое значение, объект, массив и нулевое значение в качестве значения по умолчанию. В этом примере будет использоваться синтаксис функции стрелки:
1 2 3 4 5 6 7 |
// Create functions with a default value for each data type const defaultNumber = (number = 42) => console.log(number) const defaultString = (string = 'Shark') => console.log(string) const defaultBoolean = (boolean = true) => console.log(boolean) const defaultObject = (object = { id: 7 }) => console.log(object) const defaultArray = (array = [1, 2, 3]) => console.log(array) const defaultNull = (nullValue = null) => console.log(nullValue) |
Когда эти функции вызываются без параметров, все они будут использовать значения по умолчанию:
1 2 3 4 5 6 7 |
// Invoke each function defaultNumber() defaultString() defaultBoolean() defaultObject() defaultArray() defaultNull() |
Вывод:
1 2 3 4 5 6 |
42 "Shark" true {id: 7} (3) [1, 2, 3] null |
Обратите внимание, что любой объект, созданный в параметре по умолчанию, будет создаваться при каждом вызове функции. Одним из распространенных вариантов использования параметров по умолчанию является применение этого поведения для получения значений из объекта. Если вы попытаетесь деструктурировать или получить доступ к значению из несуществующего объекта, он выдаст ошибку. Однако, если параметром по умолчанию является пустой объект, он просто выдаст undefined, а не ошибку:
1 2 3 4 5 6 |
// Define a settings function with a default object function settings(options = {}) { const { theme, debug } = options // Do something with settings } |
Это позволит избежать ошибки, вызванной деструктурированием несуществующих объектов. Теперь, когда вы увидели, как параметры по умолчанию работают с различными типами данных, в следующем разделе будет объяснено, как несколько параметров по умолчанию могут работать вместе.
Использование нескольких параметров по умолчанию
Вы можете использовать в функции столько параметров по умолчанию, сколько хотите. В этом разделе мы рассмотрим, как это сделать и как использовать его для управления DOM в реальном примере. Сначала объявите функцию sum() с несколькими параметрами по умолчанию:
1 2 3 4 5 6 |
// Define a function to add two values function sum(a = 1, b = 2) { return a + b } sum() |
Это даст следующий расчет по умолчанию: 3.
Кроме того, значение, используемое в параметре, может использоваться в любом последующем параметре по умолчанию слева направо. Например, функция createUser создает пользовательский объект userObj в качестве третьего параметра, и все, что делает сама функция, это возвращает первые два параметра userObj:
1 2 3 4 5 6 7 |
// Define a function to create a user object using parameters function createUser(name, rank, userObj = { name, rank }) { return userObj } // Create user const user = createUser('Jean-Luc Picard', 'Captain') |
Если вы вызовите user, то получите следующее: {name: «Jean-Luc Picard», rank: «Captain»}.
Обычно рекомендуется помещать все параметры по умолчанию в конец списка параметров, чтобы можно было легко пропустить необязательные значения. Если вы сначала используете параметр по умолчанию, вам придется явно передать значение по умолчанию undefined.
Вот пример с параметром по умолчанию в начале списка:
1 2 3 4 |
// Define a function with a default parameter at the start of the list function defaultFirst(a = 1, b) { return a + b } |
При вызове этой функции вам придется вызывать defaultFirst() с двумя аргументами:
1 |
defaultFirst(undefined, 2) |
Это дало бы следующий результат: 3.
Вот пример с параметром по умолчанию в конце списка:
1 2 3 4 5 6 |
// Define a function with a default parameter at the end of the list function defaultLast(a, b = 1) { return a + b } defaultLast(2) |
Это даст то же значение: 3.
Обе функции дают один и тот же результат, но та, у которой значение по умолчанию последнее, реализует намного более чистый вызов функции.
Для примера из реальной жизни, вот функция, которая создает элемент DOM и добавляет текстовую метку и классы, если они существуют.
1 2 3 4 5 6 7 8 9 10 11 |
// Define function to create an element function createNewElement(tag, text, classNames = []) { const el = document.createElement(tag) el.textContent = text classNames.forEach(className => { el.classList.add(className) }) return el } |
Вы можете вызвать функцию с некоторыми классами в массиве:
1 |
const greeting = createNewElement('p', 'Hello!', ['greeting', 'active']) |
Вызов greeting даст следующее значение:
1 |
<p class="greeting active">Hello!</p> |
Однако, если вы оставите массив classNames вне вызова функции, это все равно будет работать.
1 |
const greeting2 = createNewElement('p', 'Hello!') |
greeting2 теперь имеет следующее значение:
1 |
<p>Hello!</p> |
В этом примере forEach() может без проблем использоваться пустой массив. Если этот пустой массив не был установлен в параметре по умолчанию, вы получите следующую ошибку:
1 2 3 |
VM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined at createNewElement (<anonymous>:5:14) at <anonymous>:12:18 |
Теперь, когда вы поняли, как могут взаимодействовать несколько параметров по умолчанию, мы можем перейти к следующему разделу, чтобы рассмотреть, как вызовы функций работают в качестве параметров по умолчанию.
Вызовы функций в качестве параметров по умолчанию
В дополнение к примитивам и объектам, как параметр по умолчанию может использоваться результат вызова функции. В этом блоке кода мы создаем функцию для возврата случайного числа, а затем используем результат в качестве значения параметра по умолчанию в функции cube:
1 2 3 4 5 6 7 8 9 |
// Define a function to return a random number from 1 to 10 function getRandomNumber() { return Math.floor(Math.random() * 10) } // Use the random number function as a default parameter for the cube function function cube(x = getRandomNumber()) { return x * x * x } |
Теперь вызов функции cube без параметра будет давать потенциально разные результаты при каждом ее вызове:
1 2 3 |
// Invoke cube function twice for two potentially different results cube() cube() |
Результаты этих вызовов функций будут различными: 512 и 64.
Вы даже можете применить встроенные методы, такие как методы объекта Math, и использовать значение, возвращаемое в одном вызове функции, в качестве параметра в другой функции.
В следующем примере назначается случайное число x, которое используется в качестве параметра в функции cube, которую вы создали. Параметр y будет вычислять кубический корень из числа и проверять, равны ли x и y:
1 2 3 4 5 6 7 |
// Assign a random number to x // Assign the cube root of the result of the cube function and x to y function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) { return x === y } doesXEqualY() |
Это даст следующее: true.
Параметр по умолчанию может даже быть определением функции, как видно в этом примере, который определяет параметр как функцию inner и возвращает вызов функции parameter:
1 2 3 4 5 6 7 8 9 10 11 |
// Define a function with a default parameter that is an anonymous function function outer( parameter = function inner() { return 100 } ) { return parameter() } // Invoke outer function outer() |
Это даст следующее: 100.
Функция inner будет создаваться с нуля каждый раз, когда она вызывается outer.
Заключение
В этой статье вы узнали, что такое параметры функций по умолчанию и как их использовать. Теперь вы можете применять параметры по умолчанию, чтобы сохранить функции чистыми и удобными для чтения. Вы также можете заранее назначить параметрам пустые объекты и массивы, чтобы уменьшить сложность и количество строк кода при работе с такими ситуациями, как получение значений из объекта или циклическое перемещение по массиву.
Автор: Tania Rascia
Источник: //www.taniarascia.com
Редакция: Команда webformyself.