Объекты в функциях

Последнее обновление: 14.09.2023

Объект как результат функции

Функции могут возвращать объекты. Этот может потребоваться в различных задачах. Например, вынесем создание объекта в отдельную функцию:

function createUser(pName, pAge) {
	return {
		name: pName,
		age: pAge,
		print: function() {
			console.log(`Name: ${this.name}  Age: ${this.age}`);
		}
	};
};
const tom = createUser("Tom", 26);
tom.print();
const alice = createUser("Alice", 24);
alice.print();

Здесь функция createUser() получает значения pName и pAge и по ним создает новый объект, который является возвращаемым результатом. Результат работы программы:

Name: Tom  Age: 26
Name: Alice  Age: 24

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

function createUser(pName, pAge) {

  if(pAge < 1 || pAge > 110){       // если возраст меньше 1 или больще 110
      console.log("Age is invalid")
      pAge=1;
  }
	return {
		name: pName,
		age: pAge,
		print: function() {
			console.log(`Name: ${this.name}  Age: ${this.age}`);
		}
	};
};
const tom = createUser("Tom", 26);
tom.print();
const alice = createUser("Alice", 12345);
alice.print();

Здесь проверяется параметр pAge, который представляет возвраст пользователя. Понятно, что теоретически это может быть любое число, которое может выходить за разумные пределы, например, быть отрицательным. И в данном случае мы проверяем pAge на соответствие этому пределу. Если значение pAge не соответствует пределу, то присваиваем ему значение по умолчанию - в данном случае 1, и выводим диагностическое сообщение. Консольный вывод программы:

Name: Tom  Age: 26
Age is invalid
Name: Alice  Age: 1

Также возращение объекта может быть полезно, если нам надо ввернуть из функции больше одного результата - в этом случае мы можем объединить их в один объект. Например, функция принимает массив и находит в нем минимальное и максимальное значения:

function getMinMax(numbers){

  // если массив пуст, минимальное и максимальное значения неопределены
  if(numbers.length === 0) return {min: undefined, max: undefined};

  let minNumber = numbers[0];
  let maxNumber = numbers[0];
  for(let i=1; i< numbers.length; i++){
    
    if(minNumber > numbers[i]) minNumber = numbers[i];
    if(maxNumber < numbers[i]) maxNumber = numbers[i];
  }
  return {min: minNumber, max: maxNumber};
}

const nums = [1, 2, 3, 4, 5];
const result = getMinMax(nums);
console.log("Min:", result.min);    // Min: 1
console.log("Max:", result.max);    // Max: 5

Здесь в функции getMinMax получаем массив. Если массив не содержит чисел, то возвращаем объект, где поля min и max имеют значения undefined. Иначе проходим по всему массиву и вычисляем максимальное и минимальное значения и возвращаем их в виде одного объекта.

Объект как параметр

Как и все другие значения, объект может передаваться в качестве параметра в функцию:

function printPerson(person){

  console.log("Name:", person.name);
  console.log("Age:", person.age);
}

const tom = {name: "Tom", age: 39};
const alice = {name: "Alice", age: 35};

printPerson(tom);
printPerson(alice);

Здесь в функцию printPerson передается объект, который, как предполагается, будет иметь два свойства: name и age.

При этом стоит учитывать, что объект - ссылочный тип, а переменная/константа/параметр, которые представляют объект, фактически хранят ссылку на объект в памяти, а не сам объект. Соответственно при передаче в функцию объекта параметру передается копия ссылки на этот объект. И через эту ссылку функция может изменять различные свойства объекта:

function setAge(person, pAge){

  person.age = pAge;
}

const sam = {name: "Sam", age: 29};
console.log("Before setAge:", sam.age);
setAge(sam, 30);
console.log("After setAge:", sam.age);

Здесь сначала определяем константу sam, которая представляет объект со свойствами name и age:

const sam = {name: "Sam", age: 29};

Фактически константа sam хранит ссылку на область памяти, где расположен объект.

Затем вызывается функция setAge, которая получает объект person и изменяет у него свойство age.

setAge(sam, 30);

Поскольку объекты передаются по ссылке, то функция setAge получит копию ссылки, которая хранится в константе sam. То есть после этого константа sam и первый параметр функции setAge будут представлять две разные ссылки, но указывать они будут на один и тот же объект в памяти. Поэтому если внутри функции setAge мы изменим свойство этого объекта, то при обращении у объекта sam свойство тоже изменится, так как в реальности это один и тот же объект. В итоге браузер нам выведет:

Before setAge: 29
After setAge: 30

Но если параметру внутри функции присваивается другой объект, то фактически ссылка меняет свое значение и начинает указывать на дргую область памяти:

function setDefault(person){

  person = {name: "Undefined", age: 0};
}

let sam = {name: "Sam", age: 29};
console.log("Before setDefault:", sam.name);
setDefault(sam);
console.log("After setDefault:", sam.name);

При передаче переменной sam в функцию setDefault параметр этой функции и переменная sam будут представлять две разные ссылки, но указывать на один и тот же обеъект в памяти:

setDefault(sam);

Но потом внутри функции мы изменяем значение параметра:

person = {name: "Undefined", age: 0};

В итоге ссылке, которая хранится в параметре person, присвается новый объект. Но поскольку переменная sam и параметр person представляют две разные ссылки, то это присваивание никак не затронет объект sam.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850